RakPeer.cpp 250 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. // \file
  11. //
  12. #define CAT_NEUTER_EXPORT /* Neuter dllimport for libcat */
  13. #include "RakNetDefines.h"
  14. #include "RakPeer.h"
  15. #include "RakNetTypes.h"
  16. #ifdef _WIN32
  17. #else
  18. #include <unistd.h>
  19. #endif
  20. // #if defined(new)
  21. // #pragma push_macro("new")
  22. // #undef new
  23. // #define RMO_NEW_UNDEF_ALLOCATING_QUEUE
  24. // #endif
  25. #include <time.h>
  26. #include <ctype.h> // toupper
  27. #include <string.h>
  28. #include "GetTime.h"
  29. #include "MessageIdentifiers.h"
  30. #include "DS_HuffmanEncodingTree.h"
  31. #include "Rand.h"
  32. #include "PluginInterface2.h"
  33. #include "StringCompressor.h"
  34. #include "StringTable.h"
  35. #include "NetworkIDObject.h"
  36. #include "RakNetTypes.h"
  37. #include "DR_SHA1.h"
  38. #include "RakSleep.h"
  39. #include "RakAssert.h"
  40. #include "RakNetVersion.h"
  41. #include "NetworkIDManager.h"
  42. #include "gettimeofday.h"
  43. #include "SignaledEvent.h"
  44. #include "SuperFastHash.h"
  45. #include "RakAlloca.h"
  46. #include "WSAStartupSingleton.h"
  47. #ifdef USE_THREADED_SEND
  48. #include "SendToThread.h"
  49. #endif
  50. #ifdef CAT_AUDIT
  51. #define CAT_AUDIT_PRINTF(...) printf(__VA_ARGS__)
  52. #else
  53. #define CAT_AUDIT_PRINTF(...)
  54. #endif
  55. namespace RakNet
  56. {
  57. RAK_THREAD_DECLARATION(UpdateNetworkLoop);
  58. RAK_THREAD_DECLARATION(RecvFromLoop);
  59. RAK_THREAD_DECLARATION(UDTConnect);
  60. }
  61. #define REMOTE_SYSTEM_LOOKUP_HASH_MULTIPLE 8
  62. #if !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ )
  63. #include <stdlib.h> // malloc
  64. #endif
  65. #if defined(_WIN32)
  66. //
  67. #else
  68. /*
  69. #include <alloca.h> // Console 2
  70. #include <stdlib.h>
  71. extern bool _extern_Console2LoadModules(void);
  72. extern int _extern_Console2GetConnectionStatus(void);
  73. extern int _extern_Console2GetLobbyStatus(void);
  74. //extern bool Console2StartupFluff(unsigned int *);
  75. extern void Console2ShutdownFluff(void);
  76. //extern unsigned int Console2ActivateConnection(unsigned int, void *);
  77. //extern bool Console2BlockOnEstablished(void);
  78. extern void Console2GetIPAndPort(unsigned int, char *, unsigned short *, unsigned int );
  79. //extern void Console2DeactivateConnection(unsigned int, unsigned int);
  80. */
  81. #endif
  82. static const int NUM_MTU_SIZES=3;
  83. static const int mtuSizes[NUM_MTU_SIZES]={MAXIMUM_MTU_SIZE, 1200, 576};
  84. // Note to self - if I change this it might affect RECIPIENT_OFFLINE_MESSAGE_INTERVAL in Natpunchthrough.cpp
  85. //static const int MAX_OPEN_CONNECTION_REQUESTS=8;
  86. //static const int TIME_BETWEEN_OPEN_CONNECTION_REQUESTS=500;
  87. #ifdef _MSC_VER
  88. #pragma warning( push )
  89. #endif
  90. using namespace RakNet;
  91. static RakNetRandom rnr;
  92. /*
  93. struct RakPeerAndIndex
  94. {
  95. RakNetSocket2 *s;
  96. RakPeer *rakPeer;
  97. };
  98. */
  99. static const unsigned int MAX_OFFLINE_DATA_LENGTH=400; // I set this because I limit ID_CONNECTION_REQUEST to 512 bytes, and the password is appended to that packet.
  100. // Used to distinguish between offline messages with data, and messages from the reliability layer
  101. // Should be different than any message that could result from messages from the reliability layer
  102. #if !defined(__GNUC__)
  103. #pragma warning(disable:4309) // 'initializing' : truncation of constant value
  104. #endif
  105. // Make sure highest bit is 0, so isValid in DatagramHeaderFormat is false
  106. static const unsigned char OFFLINE_MESSAGE_DATA_ID[16]={0x00,0xFF,0xFF,0x00,0xFE,0xFE,0xFE,0xFE,0xFD,0xFD,0xFD,0xFD,0x12,0x34,0x56,0x78};
  107. struct PacketFollowedByData
  108. {
  109. Packet p;
  110. unsigned char data[1];
  111. };
  112. Packet *RakPeer::AllocPacket(unsigned dataSize, const char *file, unsigned int line)
  113. {
  114. // Crashes when dataSize is 4 bytes - not sure why
  115. // unsigned char *data = (unsigned char *) rakMalloc_Ex(sizeof(PacketFollowedByData)+dataSize, file, line);
  116. // Packet *p = &((PacketFollowedByData *)data)->p;
  117. // p->data=((PacketFollowedByData *)data)->data;
  118. // p->length=dataSize;
  119. // p->bitSize=BYTES_TO_BITS(dataSize);
  120. // p->deleteData=false;
  121. // p->guid=UNASSIGNED_RAKNET_GUID;
  122. // return p;
  123. RakNet::Packet *p;
  124. packetAllocationPoolMutex.Lock();
  125. p = packetAllocationPool.Allocate(file,line);
  126. packetAllocationPoolMutex.Unlock();
  127. p = new ((void*)p) Packet;
  128. p->data=(unsigned char*) rakMalloc_Ex(dataSize,file,line);
  129. p->length=dataSize;
  130. p->bitSize=BYTES_TO_BITS(dataSize);
  131. p->deleteData=true;
  132. p->guid=UNASSIGNED_RAKNET_GUID;
  133. p->wasGeneratedLocally=false;
  134. return p;
  135. }
  136. Packet *RakPeer::AllocPacket(unsigned dataSize, unsigned char *data, const char *file, unsigned int line)
  137. {
  138. // Packet *p = (Packet *)rakMalloc_Ex(sizeof(Packet), file, line);
  139. RakNet::Packet *p;
  140. packetAllocationPoolMutex.Lock();
  141. p = packetAllocationPool.Allocate(file,line);
  142. packetAllocationPoolMutex.Unlock();
  143. p = new ((void*)p) Packet;
  144. RakAssert(p);
  145. p->data=data;
  146. p->length=dataSize;
  147. p->bitSize=BYTES_TO_BITS(dataSize);
  148. p->deleteData=true;
  149. p->guid=UNASSIGNED_RAKNET_GUID;
  150. p->wasGeneratedLocally=false;
  151. return p;
  152. }
  153. STATIC_FACTORY_DEFINITIONS(RakPeerInterface,RakPeer)
  154. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  155. // Constructor
  156. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  157. RakPeer::RakPeer()
  158. {
  159. #if LIBCAT_SECURITY==1
  160. // Encryption and security
  161. CAT_AUDIT_PRINTF("AUDIT: Initializing RakPeer security flags: using_security = false, server_handshake = null, cookie_jar = null\n");
  162. _using_security = false;
  163. _server_handshake = 0;
  164. _cookie_jar = 0;
  165. #endif
  166. StringCompressor::AddReference();
  167. RakNet::StringTable::AddReference();
  168. WSAStartupSingleton::AddRef();
  169. defaultMTUSize = mtuSizes[NUM_MTU_SIZES-1];
  170. trackFrequencyTable = false;
  171. maximumIncomingConnections = 0;
  172. maximumNumberOfPeers = 0;
  173. //remoteSystemListSize=0;
  174. remoteSystemList = 0;
  175. activeSystemList = 0;
  176. activeSystemListSize=0;
  177. remoteSystemLookup=0;
  178. bytesSentPerSecond = bytesReceivedPerSecond = 0;
  179. endThreads = true;
  180. isMainLoopThreadActive = false;
  181. incomingDatagramEventHandler=0;
  182. // isRecvfromThreadActive=false;
  183. #if defined(GET_TIME_SPIKE_LIMIT) && GET_TIME_SPIKE_LIMIT>0
  184. occasionalPing = true;
  185. #else
  186. occasionalPing = false;
  187. #endif
  188. allowInternalRouting=false;
  189. for (unsigned int i=0; i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++)
  190. ipList[i]=UNASSIGNED_SYSTEM_ADDRESS;
  191. allowConnectionResponseIPMigration = false;
  192. //incomingPasswordLength=outgoingPasswordLength=0;
  193. incomingPasswordLength=0;
  194. splitMessageProgressInterval=0;
  195. //unreliableTimeout=0;
  196. unreliableTimeout=1000;
  197. maxOutgoingBPS=0;
  198. firstExternalID=UNASSIGNED_SYSTEM_ADDRESS;
  199. myGuid=UNASSIGNED_RAKNET_GUID;
  200. userUpdateThreadPtr=0;
  201. userUpdateThreadData=0;
  202. #ifdef _DEBUG
  203. // Wait longer to disconnect in debug so I don't get disconnected while tracing
  204. defaultTimeoutTime=30000;
  205. #else
  206. defaultTimeoutTime=10000;
  207. #endif
  208. #ifdef _DEBUG
  209. _packetloss=0.0;
  210. _minExtraPing=0;
  211. _extraPingVariance=0;
  212. #endif
  213. bufferedCommands.SetPageSize(sizeof(BufferedCommandStruct)*16);
  214. socketQueryOutput.SetPageSize(sizeof(SocketQueryOutput)*8);
  215. packetAllocationPoolMutex.Lock();
  216. packetAllocationPool.SetPageSize(sizeof(DataStructures::MemoryPool<Packet>::MemoryWithPage)*32);
  217. packetAllocationPoolMutex.Unlock();
  218. remoteSystemIndexPool.SetPageSize(sizeof(DataStructures::MemoryPool<RemoteSystemIndex>::MemoryWithPage)*32);
  219. GenerateGUID();
  220. quitAndDataEvents.InitEvent();
  221. limitConnectionFrequencyFromTheSameIP=false;
  222. ResetSendReceipt();
  223. }
  224. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  225. // Destructor
  226. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  227. RakPeer::~RakPeer()
  228. {
  229. Shutdown( 0, 0 );
  230. // Free the ban list.
  231. ClearBanList();
  232. StringCompressor::RemoveReference();
  233. RakNet::StringTable::RemoveReference();
  234. WSAStartupSingleton::Deref();
  235. quitAndDataEvents.CloseEvent();
  236. #if LIBCAT_SECURITY==1
  237. // Encryption and security
  238. CAT_AUDIT_PRINTF("AUDIT: Deleting RakPeer security objects, handshake = %x, cookie jar = %x\n", _server_handshake, _cookie_jar);
  239. if (_server_handshake) RakNet::OP_DELETE(_server_handshake,_FILE_AND_LINE_);
  240. if (_cookie_jar) RakNet::OP_DELETE(_cookie_jar,_FILE_AND_LINE_);
  241. #endif
  242. // for (unsigned int i=0; i < pluginListTS.Size(); i++)
  243. // pluginListTS[i]->SetRakPeerInterface(0);
  244. // for (unsigned int i=0; i < pluginListNTS.Size(); i++)
  245. // pluginListNTS[i]->SetRakPeerInterface(0);
  246. }
  247. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  248. // \brief Starts the network threads, opens the listen port.
  249. // You must call this before calling Connect().
  250. // Multiple calls while already active are ignored. To call this function again with different settings, you must first call Shutdown().
  251. // \note Call SetMaximumIncomingConnections if you want to accept incoming connections
  252. // \param[in] maxConnections The maximum number of connections between this instance of RakPeer and another instance of RakPeer. Required so the network can preallocate and for thread safety. A pure client would set this to 1. A pure server would set it to the number of allowed clients.- A hybrid would set it to the sum of both types of connections
  253. // \param[in] localPort The port to listen for connections on.
  254. // \param[in] _threadSleepTimer How many ms to Sleep each internal update cycle. With new congestion control, the best results will be obtained by passing 10.
  255. // \param[in] socketDescriptors An array of SocketDescriptor structures to force RakNet to listen on a particular IP address or port (or both). Each SocketDescriptor will represent one unique socket. Do not pass redundant structures. To listen on a specific port, you can pass &socketDescriptor, 1SocketDescriptor(myPort,0); such as for a server. For a client, it is usually OK to just pass SocketDescriptor();
  256. // \param[in] socketDescriptorCount The size of the \a socketDescriptors array. Pass 1 if you are not sure what to pass.
  257. // \return False on failure (can't create socket or thread), true on success.
  258. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  259. StartupResult RakPeer::Startup( unsigned int maxConnections, SocketDescriptor *socketDescriptors, unsigned socketDescriptorCount, int threadPriority )
  260. {
  261. if (IsActive())
  262. return RAKNET_ALREADY_STARTED;
  263. // If getting the guid failed in the constructor, try again
  264. if (myGuid.g==0)
  265. {
  266. GenerateGUID();
  267. if (myGuid.g==0)
  268. return COULD_NOT_GENERATE_GUID;
  269. }
  270. if (threadPriority==-99999)
  271. {
  272. #if defined(_WIN32)
  273. threadPriority=0;
  274. #else
  275. threadPriority=1000;
  276. #endif
  277. }
  278. FillIPList();
  279. if (myGuid==UNASSIGNED_RAKNET_GUID)
  280. {
  281. rnr.SeedMT( GenerateSeedFromGuid() );
  282. }
  283. //RakPeerAndIndex rpai[32];
  284. //RakAssert(socketDescriptorCount<32);
  285. RakAssert(socketDescriptors && socketDescriptorCount>=1);
  286. if (socketDescriptors==0 || socketDescriptorCount<1)
  287. return INVALID_SOCKET_DESCRIPTORS;
  288. //unsigned short localPort;
  289. //localPort=socketDescriptors[0].port;
  290. RakAssert( maxConnections > 0 );
  291. if ( maxConnections <= 0 )
  292. return INVALID_MAX_CONNECTIONS;
  293. DerefAllSockets();
  294. int i;
  295. // Go through all socket descriptors and precreate sockets on the specified addresses
  296. for (i=0; i<socketDescriptorCount; i++)
  297. {
  298. /*
  299. const char *addrToBind;
  300. if (socketDescriptors[i].hostAddress[0]==0)
  301. addrToBind=0;
  302. else
  303. addrToBind=socketDescriptors[i].hostAddress;
  304. */
  305. /*
  306. #if RAKNET_SUPPORT_IPV6==1
  307. if (SocketLayer::IsSocketFamilySupported(addrToBind, socketDescriptors[i].socketFamily)==false)
  308. return SOCKET_FAMILY_NOT_SUPPORTED;
  309. #endif
  310. if (socketDescriptors[i].port!=0 && SocketLayer::IsPortInUse(socketDescriptors[i].port, addrToBind, socketDescriptors[i].socketFamily)==true)
  311. {
  312. DerefAllSockets();
  313. return SOCKET_PORT_ALREADY_IN_USE;
  314. }
  315. RakNetSocket* rns = 0;
  316. if (socketDescriptors[i].remotePortRakNetWasStartedOn_PS3_PSP2==0)
  317. {
  318. rns = SocketLayer::CreateBoundSocket( this, socketDescriptors[i].port, socketDescriptors[i].blockingSocket, addrToBind, 100, socketDescriptors[i].extraSocketOptions, socketDescriptors[i].socketFamily, socketDescriptors[i].chromeInstance );
  319. }
  320. else
  321. {
  322. #if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3) || defined(_PS4)
  323. rns = SocketLayer::CreateBoundSocket_PS3Lobby( socketDescriptors[i].port, socketDescriptors[i].blockingSocket, addrToBind, socketDescriptors[i].socketFamily );
  324. #elif defined(SN_TARGET_PSP2)
  325. rns = SocketLayer::CreateBoundSocket_PSP2( socketDescriptors[i].port, socketDescriptors[i].blockingSocket, addrToBind, socketDescriptors[i].socketFamily );
  326. #endif
  327. }
  328. */
  329. RakNetSocket2 *r2 = RakNetSocket2Allocator::AllocRNS2();
  330. r2->SetUserConnectionSocketIndex(i);
  331. #if defined(__native_client__)
  332. NativeClientBindParameters ncbp;
  333. RNS2_NativeClient * nativeClientSocket = (RNS2_NativeClient*) r2;
  334. ncbp.eventHandler=this;
  335. ncbp.forceHostAddress=(char*) socketDescriptors[i].hostAddress;
  336. ncbp.is_ipv6=socketDescriptors[i].socketFamily==AF_INET6;
  337. ncbp.nativeClientInstance=socketDescriptors[i].chromeInstance;
  338. ncbp.port=socketDescriptors[i].port;
  339. nativeClientSocket->Bind(&ncbp, _FILE_AND_LINE_);
  340. #elif defined(WINDOWS_STORE_RT)
  341. RNS2BindResult br;
  342. ((RNS2_WindowsStore8*) r2)->SetRecvEventHandler(this);
  343. br = ((RNS2_WindowsStore8*) r2)->Bind(ref new Platform::String());
  344. if (br!=BR_SUCCESS)
  345. {
  346. RakNetSocket2Allocator::DeallocRNS2(r2);
  347. DerefAllSockets();
  348. return SOCKET_FAILED_TO_BIND;
  349. }
  350. #else
  351. if (r2->IsBerkleySocket())
  352. {
  353. RNS2_BerkleyBindParameters bbp;
  354. bbp.port=socketDescriptors[i].port;
  355. bbp.hostAddress=(char*) socketDescriptors[i].hostAddress;
  356. bbp.addressFamily=socketDescriptors[i].socketFamily;
  357. bbp.type=SOCK_DGRAM;
  358. bbp.protocol=socketDescriptors[i].extraSocketOptions;
  359. bbp.nonBlockingSocket=false;
  360. bbp.setBroadcast=true;
  361. bbp.setIPHdrIncl=false;
  362. bbp.doNotFragment=false;
  363. bbp.pollingThreadPriority=threadPriority;
  364. bbp.eventHandler=this;
  365. bbp.remotePortRakNetWasStartedOn_PS3_PS4_PSP2=socketDescriptors[i].remotePortRakNetWasStartedOn_PS3_PSP2;
  366. RNS2BindResult br = ((RNS2_Berkley*) r2)->Bind(&bbp, _FILE_AND_LINE_);
  367. if (
  368. #if RAKNET_SUPPORT_IPV6==0
  369. socketDescriptors[i].socketFamily!=AF_INET ||
  370. #endif
  371. br==BR_REQUIRES_RAKNET_SUPPORT_IPV6_DEFINE)
  372. {
  373. RakNetSocket2Allocator::DeallocRNS2(r2);
  374. DerefAllSockets();
  375. return SOCKET_FAMILY_NOT_SUPPORTED;
  376. }
  377. else if (br==BR_FAILED_TO_BIND_SOCKET)
  378. {
  379. RakNetSocket2Allocator::DeallocRNS2(r2);
  380. DerefAllSockets();
  381. return SOCKET_PORT_ALREADY_IN_USE;
  382. }
  383. else if (br==BR_FAILED_SEND_TEST)
  384. {
  385. RakNetSocket2Allocator::DeallocRNS2(r2);
  386. DerefAllSockets();
  387. return SOCKET_FAILED_TEST_SEND;
  388. }
  389. else
  390. {
  391. RakAssert(br==BR_SUCCESS);
  392. }
  393. }
  394. else
  395. {
  396. RakAssert("TODO" && 0);
  397. }
  398. #endif
  399. /*
  400. SystemAddress saOut;
  401. SocketLayer::GetSystemAddress( rns, &saOut );
  402. rns->SetBoundAddress(saOut);
  403. rns->SetRemotePortRakNetWasStartedOn(socketDescriptors[i].remotePortRakNetWasStartedOn_PS3_PSP2);
  404. rns->SetChromeInstance(socketDescriptors[i].chromeInstance);
  405. rns->SetExtraSocketOptions(socketDescriptors[i].extraSocketOptions);
  406. rns->SetUserConnectionSocketIndex(i);
  407. rns->SetBlockingSocket(socketDescriptors[i].blockingSocket);
  408. #if RAKNET_SUPPORT_IPV6==0
  409. if (addrToBind==0)
  410. rns->SetBoundAddressToLoopback(4);
  411. #endif
  412. // GetBoundAddress is asynch, which isn't supported by this architecture
  413. #if !defined(__native_client__)
  414. int zero=0;
  415. if (SocketLayer::SendTo(rns, (const char*) &zero,4, rns->GetBoundAddress(), _FILE_AND_LINE_)!=0)
  416. {
  417. DerefAllSockets();
  418. return SOCKET_FAILED_TEST_SEND;
  419. }
  420. #endif
  421. */
  422. socketList.Push(r2, _FILE_AND_LINE_ );
  423. }
  424. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  425. for (i=0; i<socketDescriptorCount; i++)
  426. {
  427. if (socketList[i]->IsBerkleySocket())
  428. ((RNS2_Berkley*) socketList[i])->CreateRecvPollingThread(threadPriority);
  429. }
  430. #endif
  431. // #if !defined(_XBOX) && !defined(_XBOX_720_COMPILE_AS_WINDOWS) && !defined(X360)
  432. for (i=0; i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++)
  433. {
  434. if (ipList[i]==UNASSIGNED_SYSTEM_ADDRESS)
  435. break;
  436. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  437. if (socketList[0]->IsBerkleySocket())
  438. {
  439. unsigned short port = ((RNS2_Berkley*)socketList[0])->GetBoundAddress().GetPort();
  440. ipList[i].SetPortHostOrder(port);
  441. }
  442. #endif
  443. // ipList[i].SetPort(((RNS2_360_720*)socketList[0])->GetBoundAddress().GetPort());
  444. }
  445. // #endif
  446. if ( maximumNumberOfPeers == 0 )
  447. {
  448. // Don't allow more incoming connections than we have peers.
  449. if ( maximumIncomingConnections > maxConnections )
  450. maximumIncomingConnections = maxConnections;
  451. maximumNumberOfPeers = maxConnections;
  452. // 04/19/2006 - Don't overallocate because I'm no longer allowing connected pings.
  453. // The disconnects are not consistently processed and the process was sloppy and complicated.
  454. // Allocate 10% extra to handle new connections from players trying to connect when the server is full
  455. //remoteSystemListSize = maxConnections;// * 11 / 10 + 1;
  456. // remoteSystemList in Single thread
  457. //remoteSystemList = RakNet::OP_NEW<RemoteSystemStruct[ remoteSystemListSize ]>( _FILE_AND_LINE_ );
  458. remoteSystemList = RakNet::OP_NEW_ARRAY<RemoteSystemStruct>(maximumNumberOfPeers, _FILE_AND_LINE_ );
  459. remoteSystemLookup = RakNet::OP_NEW_ARRAY<RemoteSystemIndex*>((unsigned int) maximumNumberOfPeers * REMOTE_SYSTEM_LOOKUP_HASH_MULTIPLE, _FILE_AND_LINE_ );
  460. activeSystemList = RakNet::OP_NEW_ARRAY<RemoteSystemStruct*>(maximumNumberOfPeers, _FILE_AND_LINE_ );
  461. for ( i = 0; i < maximumNumberOfPeers; i++ )
  462. //for ( i = 0; i < remoteSystemListSize; i++ )
  463. {
  464. // remoteSystemList in Single thread
  465. remoteSystemList[ i ].isActive = false;
  466. remoteSystemList[ i ].systemAddress = UNASSIGNED_SYSTEM_ADDRESS;
  467. remoteSystemList[ i ].guid = UNASSIGNED_RAKNET_GUID;
  468. remoteSystemList[ i ].myExternalSystemAddress = UNASSIGNED_SYSTEM_ADDRESS;
  469. remoteSystemList[ i ].connectMode=RemoteSystemStruct::NO_ACTION;
  470. remoteSystemList[ i ].MTUSize = defaultMTUSize;
  471. remoteSystemList[ i ].remoteSystemIndex = (SystemIndex) i;
  472. #ifdef _DEBUG
  473. remoteSystemList[ i ].reliabilityLayer.ApplyNetworkSimulator(_packetloss, _minExtraPing, _extraPingVariance);
  474. #endif
  475. // All entries in activeSystemList have valid pointers all the time.
  476. activeSystemList[ i ] = &remoteSystemList[ i ];
  477. }
  478. for (unsigned int i=0; i < (unsigned int) maximumNumberOfPeers*REMOTE_SYSTEM_LOOKUP_HASH_MULTIPLE; i++)
  479. {
  480. remoteSystemLookup[i]=0;
  481. }
  482. }
  483. // For histogram statistics
  484. // nextReadBytesTime=0;
  485. // lastSentBytes=lastReceivedBytes=0;
  486. if ( endThreads )
  487. {
  488. updateCycleIsRunning = false;
  489. endThreads = false;
  490. firstExternalID=UNASSIGNED_SYSTEM_ADDRESS;
  491. ClearBufferedCommands();
  492. ClearBufferedPackets();
  493. ClearSocketQueryOutput();
  494. if ( isMainLoopThreadActive == false )
  495. {
  496. #if RAKPEER_USER_THREADED!=1
  497. int errorCode;
  498. errorCode = RakNet::RakThread::Create(UpdateNetworkLoop, this, threadPriority);
  499. if ( errorCode != 0 )
  500. {
  501. Shutdown( 0, 0 );
  502. return FAILED_TO_CREATE_NETWORK_THREAD;
  503. }
  504. // RakAssert(isRecvFromLoopThreadActive.GetValue()==0);
  505. #endif // RAKPEER_USER_THREADED!=1
  506. /*
  507. for (i=0; i<socketDescriptorCount; i++)
  508. {
  509. RakPeerAndIndex *rpai = RakNet::OP_NEW<RakPeerAndIndex>(_FILE_AND_LINE_);
  510. rpai->s=socketList[i];
  511. rpai->rakPeer=this;
  512. #if RAKPEER_USER_THREADED!=1
  513. #if defined(SN_TARGET_PSP2)
  514. sprintf(threadName, "RecvFromLoop_%p", this);
  515. //errorCode = RakNet::RakThread::Create(RecvFromLoop, rpai, threadPriority, threadName, 1+i, runtime);
  516. errorCode = RakNet::RakThread::Create(RecvFromLoop, rpai, threadPriority, threadName, 1024*1);
  517. #else
  518. errorCode = RakNet::RakThread::Create(RecvFromLoop, rpai, threadPriority);
  519. #endif
  520. if ( errorCode != 0 )
  521. {
  522. Shutdown( 0, 0 );
  523. return FAILED_TO_CREATE_NETWORK_THREAD;
  524. }
  525. #endif // RAKPEER_USER_THREADED!=1
  526. }
  527. */
  528. /*
  529. #if RAKPEER_USER_THREADED!=1
  530. while ( isRecvFromLoopThreadActive.GetValue() < (uint32_t) socketDescriptorCount )
  531. RakSleep(10);
  532. #endif // RAKPEER_USER_THREADED!=1
  533. */
  534. }
  535. #if RAKPEER_USER_THREADED!=1
  536. // Wait for the threads to activate. When they are active they will set these variables to true
  537. while ( isMainLoopThreadActive == false )
  538. RakSleep(10);
  539. #endif // RAKPEER_USER_THREADED!=1
  540. }
  541. for (i=0; i < pluginListTS.Size(); i++)
  542. {
  543. pluginListTS[i]->OnRakPeerStartup();
  544. }
  545. for (i=0; i < pluginListNTS.Size(); i++)
  546. {
  547. pluginListNTS[i]->OnRakPeerStartup();
  548. }
  549. #ifdef USE_THREADED_SEND
  550. RakNet::SendToThread::AddRef();
  551. #endif
  552. return RAKNET_STARTED;
  553. }
  554. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  555. // Description:
  556. // Must be called while offline
  557. //
  558. // If you accept connections, you must call this or else security will not be enabled for incoming connections.
  559. //
  560. // This feature requires more round trips, bandwidth, and CPU time for the connection handshake
  561. // x64 builds require under 25% of the CPU time of other builds
  562. //
  563. // See the Encryption sample for example usage
  564. //
  565. // Parameters:
  566. // publicKey = A pointer to the public key for accepting new connections
  567. // privateKey = A pointer to the private key for accepting new connections
  568. // If the private keys are 0, then a new key will be generated when this function is called
  569. // bRequireClientKey: Should be set to false for most servers. Allows the server to accept a public key from connecting clients as a proof of identity but eats twice as much CPU time as a normal connection
  570. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  571. bool RakPeer::InitializeSecurity(const char *public_key, const char *private_key, bool bRequireClientKey)
  572. {
  573. #if LIBCAT_SECURITY==1
  574. if ( endThreads == false )
  575. return false;
  576. // Copy client public key requirement flag
  577. _require_client_public_key = bRequireClientKey;
  578. if (_server_handshake)
  579. {
  580. CAT_AUDIT_PRINTF("AUDIT: Deleting old server_handshake %x\n", _server_handshake);
  581. RakNet::OP_DELETE(_server_handshake,_FILE_AND_LINE_);
  582. }
  583. if (_cookie_jar)
  584. {
  585. CAT_AUDIT_PRINTF("AUDIT: Deleting old cookie jar %x\n", _cookie_jar);
  586. RakNet::OP_DELETE(_cookie_jar,_FILE_AND_LINE_);
  587. }
  588. _server_handshake = RakNet::OP_NEW<cat::ServerEasyHandshake>(_FILE_AND_LINE_);
  589. _cookie_jar = RakNet::OP_NEW<cat::CookieJar>(_FILE_AND_LINE_);
  590. CAT_AUDIT_PRINTF("AUDIT: Created new server_handshake %x\n", _server_handshake);
  591. CAT_AUDIT_PRINTF("AUDIT: Created new cookie jar %x\n", _cookie_jar);
  592. CAT_AUDIT_PRINTF("AUDIT: Running _server_handshake->Initialize()\n");
  593. if (_server_handshake->Initialize(public_key, private_key))
  594. {
  595. CAT_AUDIT_PRINTF("AUDIT: Successfully initialized, filling cookie jar with goodies, storing public key and setting using security flag to true\n");
  596. _server_handshake->FillCookieJar(_cookie_jar);
  597. memcpy(my_public_key, public_key, sizeof(my_public_key));
  598. _using_security = true;
  599. return true;
  600. }
  601. CAT_AUDIT_PRINTF("AUDIT: Failure to initialize so deleting server handshake and cookie jar; also setting using_security flag = false\n");
  602. RakNet::OP_DELETE(_server_handshake,_FILE_AND_LINE_);
  603. _server_handshake=0;
  604. RakNet::OP_DELETE(_cookie_jar,_FILE_AND_LINE_);
  605. _cookie_jar=0;
  606. _using_security = false;
  607. return false;
  608. #else
  609. (void) public_key;
  610. (void) private_key;
  611. (void) bRequireClientKey;
  612. return false;
  613. #endif
  614. }
  615. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  616. // Description
  617. // Must be called while offline
  618. // Disables security for incoming connections.
  619. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  620. void RakPeer::DisableSecurity( void )
  621. {
  622. #if LIBCAT_SECURITY==1
  623. CAT_AUDIT_PRINTF("AUDIT: DisableSecurity() called, so deleting _server_handshake %x and cookie_jar %x\n", _server_handshake, _cookie_jar);
  624. RakNet::OP_DELETE(_server_handshake,_FILE_AND_LINE_);
  625. _server_handshake=0;
  626. RakNet::OP_DELETE(_cookie_jar,_FILE_AND_LINE_);
  627. _cookie_jar=0;
  628. _using_security = false;
  629. #endif
  630. }
  631. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  632. void RakPeer::AddToSecurityExceptionList(const char *ip)
  633. {
  634. securityExceptionMutex.Lock();
  635. securityExceptionList.Insert(RakString(ip), _FILE_AND_LINE_);
  636. securityExceptionMutex.Unlock();
  637. }
  638. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  639. void RakPeer::RemoveFromSecurityExceptionList(const char *ip)
  640. {
  641. if (securityExceptionList.Size()==0)
  642. return;
  643. if (ip==0)
  644. {
  645. securityExceptionMutex.Lock();
  646. securityExceptionList.Clear(false, _FILE_AND_LINE_);
  647. securityExceptionMutex.Unlock();
  648. }
  649. else
  650. {
  651. unsigned i=0;
  652. securityExceptionMutex.Lock();
  653. while (i < securityExceptionList.Size())
  654. {
  655. if (securityExceptionList[i].IPAddressMatch(ip))
  656. {
  657. securityExceptionList[i]=securityExceptionList[securityExceptionList.Size()-1];
  658. securityExceptionList.RemoveAtIndex(securityExceptionList.Size()-1);
  659. }
  660. else
  661. i++;
  662. }
  663. securityExceptionMutex.Unlock();
  664. }
  665. }
  666. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  667. bool RakPeer::IsInSecurityExceptionList(const char *ip)
  668. {
  669. if (securityExceptionList.Size()==0)
  670. return false;
  671. unsigned i=0;
  672. securityExceptionMutex.Lock();
  673. for (; i < securityExceptionList.Size(); i++)
  674. {
  675. if (securityExceptionList[i].IPAddressMatch(ip))
  676. {
  677. securityExceptionMutex.Unlock();
  678. return true;
  679. }
  680. }
  681. securityExceptionMutex.Unlock();
  682. return false;
  683. }
  684. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  685. // Description:
  686. // Sets how many incoming connections are allowed. If this is less than the number of players currently connected, no
  687. // more players will be allowed to connect. If this is greater than the maximum number of peers allowed, it will be reduced
  688. // to the maximum number of peers allowed. Defaults to 0.
  689. //
  690. // Parameters:
  691. // numberAllowed - Maximum number of incoming connections allowed.
  692. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  693. void RakPeer::SetMaximumIncomingConnections( unsigned short numberAllowed )
  694. {
  695. maximumIncomingConnections = numberAllowed;
  696. }
  697. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  698. // Description:
  699. // Returns the maximum number of incoming connections, which is always <= maxConnections
  700. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  701. unsigned int RakPeer::GetMaximumIncomingConnections( void ) const
  702. {
  703. return maximumIncomingConnections;
  704. }
  705. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  706. // Returns how many open connections there are at this time
  707. // \return the number of open connections
  708. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  709. unsigned short RakPeer::NumberOfConnections(void) const
  710. {
  711. DataStructures::List<SystemAddress> addresses;
  712. DataStructures::List<RakNetGUID> guids;
  713. GetSystemList(addresses, guids);
  714. return (unsigned short) addresses.Size();
  715. }
  716. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  717. // Description:
  718. // Sets the password incoming connections must match in the call to Connect (defaults to none)
  719. // Pass 0 to passwordData to specify no password
  720. //
  721. // Parameters:
  722. // passwordData: A data block that incoming connections must match. This can be just a password, or can be a stream of data.
  723. // - Specify 0 for no password data
  724. // passwordDataLength: The length in bytes of passwordData
  725. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  726. void RakPeer::SetIncomingPassword( const char* passwordData, int passwordDataLength )
  727. {
  728. //if (passwordDataLength > MAX_OFFLINE_DATA_LENGTH)
  729. // passwordDataLength=MAX_OFFLINE_DATA_LENGTH;
  730. if (passwordDataLength > 255)
  731. passwordDataLength=255;
  732. if (passwordData==0)
  733. passwordDataLength=0;
  734. // Not threadsafe but it's not important enough to lock. Who is going to change the password a lot during runtime?
  735. // It won't overflow at least because incomingPasswordLength is an unsigned char
  736. if (passwordDataLength>0)
  737. memcpy(incomingPassword, passwordData, passwordDataLength);
  738. incomingPasswordLength=(unsigned char)passwordDataLength;
  739. }
  740. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  741. void RakPeer::GetIncomingPassword( char* passwordData, int *passwordDataLength )
  742. {
  743. if (passwordData==0)
  744. {
  745. *passwordDataLength=incomingPasswordLength;
  746. return;
  747. }
  748. if (*passwordDataLength > incomingPasswordLength)
  749. *passwordDataLength=incomingPasswordLength;
  750. if (*passwordDataLength>0)
  751. memcpy(passwordData, incomingPassword, *passwordDataLength);
  752. }
  753. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  754. // Description:
  755. // Call this to connect to the specified host (ip or domain name) and server port.
  756. // Calling Connect and not calling SetMaximumIncomingConnections acts as a dedicated client. Calling both acts as a true peer.
  757. // This is a non-blocking connection. You know the connection is successful when IsConnected() returns true
  758. // or receive gets a packet with the type identifier ID_CONNECTION_REQUEST_ACCEPTED. If the connection is not
  759. // successful, such as rejected connection or no response then neither of these things will happen.
  760. // Requires that you first call Initialize
  761. //
  762. // Parameters:
  763. // host: Either a dotted IP address or a domain name
  764. // remotePort: Which port to connect to on the remote machine.
  765. // passwordData: A data block that must match the data block on the server. This can be just a password, or can be a stream of data
  766. // passwordDataLength: The length in bytes of passwordData
  767. //
  768. // Returns:
  769. // True on successful initiation. False on incorrect parameters, internal error, or too many existing peers
  770. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  771. ConnectionAttemptResult RakPeer::Connect( const char* host, unsigned short remotePort, const char *passwordData, int passwordDataLength, PublicKey *publicKey, unsigned connectionSocketIndex, unsigned sendConnectionAttemptCount, unsigned timeBetweenSendConnectionAttemptsMS, RakNet::TimeMS timeoutTime )
  772. {
  773. // If endThreads is true here you didn't call Startup() first.
  774. if ( host == 0 || endThreads || connectionSocketIndex>=socketList.Size() )
  775. return INVALID_PARAMETER;
  776. RakAssert(remotePort!=0);
  777. connectionSocketIndex=GetRakNetSocketFromUserConnectionSocketIndex(connectionSocketIndex);
  778. if (passwordDataLength>255)
  779. passwordDataLength=255;
  780. if (passwordData==0)
  781. passwordDataLength=0;
  782. // Not threadsafe but it's not important enough to lock. Who is going to change the password a lot during runtime?
  783. // It won't overflow at least because outgoingPasswordLength is an unsigned char
  784. // if (passwordDataLength>0)
  785. // memcpy(outgoingPassword, passwordData, passwordDataLength);
  786. // outgoingPasswordLength=(unsigned char) passwordDataLength;
  787. // 04/02/09 - Can't remember why I disabled connecting to self, but it seems to work
  788. // Connecting to ourselves in the same instance of the program?
  789. // if ( ( strcmp( host, "127.0.0.1" ) == 0 || strcmp( host, "0.0.0.0" ) == 0 ) && remotePort == mySystemAddress[0].port )
  790. // return false;
  791. return SendConnectionRequest( host, remotePort, passwordData, passwordDataLength, publicKey, connectionSocketIndex, 0, sendConnectionAttemptCount, timeBetweenSendConnectionAttemptsMS, timeoutTime);
  792. }
  793. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  794. ConnectionAttemptResult RakPeer::ConnectWithSocket(const char* host, unsigned short remotePort, const char *passwordData, int passwordDataLength, RakNetSocket2* socket, PublicKey *publicKey, unsigned sendConnectionAttemptCount, unsigned timeBetweenSendConnectionAttemptsMS, RakNet::TimeMS timeoutTime)
  795. {
  796. if ( host == 0 || endThreads || socket == 0 )
  797. return INVALID_PARAMETER;
  798. if (passwordDataLength>255)
  799. passwordDataLength=255;
  800. if (passwordData==0)
  801. passwordDataLength=0;
  802. return SendConnectionRequest( host, remotePort, passwordData, passwordDataLength, publicKey, 0, 0, sendConnectionAttemptCount, timeBetweenSendConnectionAttemptsMS, timeoutTime, socket );
  803. }
  804. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  805. // Description:
  806. // Stops the network threads and close all connections. Multiple calls are ok.
  807. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  808. void RakPeer::Shutdown( unsigned int blockDuration, unsigned char orderingChannel, PacketPriority disconnectionNotificationPriority )
  809. {
  810. unsigned i,j;
  811. bool anyActive;
  812. RakNet::TimeMS startWaitingTime;
  813. // SystemAddress systemAddress;
  814. RakNet::TimeMS time;
  815. //unsigned short systemListSize = remoteSystemListSize; // This is done for threading reasons
  816. unsigned int systemListSize = maximumNumberOfPeers;
  817. if ( blockDuration > 0 )
  818. {
  819. for ( i = 0; i < systemListSize; i++ )
  820. {
  821. // remoteSystemList in user thread
  822. if (remoteSystemList[i].isActive)
  823. NotifyAndFlagForShutdown(remoteSystemList[i].systemAddress, false, orderingChannel, disconnectionNotificationPriority);
  824. }
  825. time = RakNet::GetTimeMS();
  826. startWaitingTime = time;
  827. while ( time - startWaitingTime < blockDuration )
  828. {
  829. anyActive=false;
  830. for (j=0; j < systemListSize; j++)
  831. {
  832. // remoteSystemList in user thread
  833. if (remoteSystemList[j].isActive)
  834. {
  835. anyActive=true;
  836. break;
  837. }
  838. }
  839. // If this system is out of packets to send, then stop waiting
  840. if ( anyActive==false )
  841. break;
  842. // This will probably cause the update thread to run which will probably
  843. // send the disconnection notification
  844. RakSleep(15);
  845. time = RakNet::GetTimeMS();
  846. }
  847. }
  848. for (i=0; i < pluginListTS.Size(); i++)
  849. {
  850. pluginListTS[i]->OnRakPeerShutdown();
  851. }
  852. for (i=0; i < pluginListNTS.Size(); i++)
  853. {
  854. pluginListNTS[i]->OnRakPeerShutdown();
  855. }
  856. activeSystemListSize=0;
  857. quitAndDataEvents.SetEvent();
  858. endThreads = true;
  859. // RakNet::TimeMS timeout;
  860. #if RAKPEER_USER_THREADED!=1
  861. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  862. for (i=0; i < socketList.Size(); i++)
  863. {
  864. if (socketList[i]->IsBerkleySocket())
  865. {
  866. ((RNS2_Berkley *)socketList[i])->SignalStopRecvPollingThread();
  867. }
  868. }
  869. #endif
  870. /*
  871. // Get recvfrom to unblock
  872. for (i=0; i < socketList.Size(); i++)
  873. {
  874. if (SocketLayer::SendTo(socketList[i], (const char*) &i,1,socketList[i]->GetBoundAddress(), _FILE_AND_LINE_)!=0)
  875. break;
  876. }
  877. */
  878. while ( isMainLoopThreadActive )
  879. {
  880. endThreads = true;
  881. RakSleep(15);
  882. }
  883. /*
  884. timeout = RakNet::GetTimeMS()+1000;
  885. while ( isRecvFromLoopThreadActive.GetValue()>0 && RakNet::GetTimeMS()<timeout )
  886. {
  887. // Get recvfrom to unblock
  888. for (i=0; i < socketList.Size(); i++)
  889. {
  890. SocketLayer::SendTo(socketList[i], (const char*) &i,1,socketList[i]->GetBoundAddress(), _FILE_AND_LINE_);
  891. }
  892. RakSleep(30);
  893. }
  894. */
  895. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  896. for (i=0; i < socketList.Size(); i++)
  897. {
  898. if (socketList[i]->IsBerkleySocket())
  899. {
  900. ((RNS2_Berkley *)socketList[i])->BlockOnStopRecvPollingThread();
  901. }
  902. }
  903. #endif
  904. #endif // RAKPEER_USER_THREADED!=1
  905. // char c=0;
  906. // unsigned int socketIndex;
  907. // remoteSystemList in Single thread
  908. for ( i = 0; i < systemListSize; i++ )
  909. {
  910. // Reserve this reliability layer for ourselves
  911. remoteSystemList[ i ].isActive = false;
  912. // Remove any remaining packets
  913. RakAssert(remoteSystemList[ i ].MTUSize <= MAXIMUM_MTU_SIZE);
  914. remoteSystemList[ i ].reliabilityLayer.Reset(false, remoteSystemList[ i ].MTUSize, false);
  915. remoteSystemList[ i ].rakNetSocket = 0;
  916. }
  917. // Setting maximumNumberOfPeers to 0 allows remoteSystemList to be reallocated in Initialize.
  918. // Setting remoteSystemListSize prevents threads from accessing the reliability layer
  919. maximumNumberOfPeers = 0;
  920. //remoteSystemListSize = 0;
  921. // Free any packets the user didn't deallocate
  922. packetReturnMutex.Lock();
  923. for (i=0; i < packetReturnQueue.Size(); i++)
  924. DeallocatePacket(packetReturnQueue[i]);
  925. packetReturnQueue.Clear(_FILE_AND_LINE_);
  926. packetReturnMutex.Unlock();
  927. packetAllocationPoolMutex.Lock();
  928. packetAllocationPool.Clear(_FILE_AND_LINE_);
  929. packetAllocationPoolMutex.Unlock();
  930. /*
  931. if (isRecvFromLoopThreadActive.GetValue()>0)
  932. {
  933. timeout = RakNet::GetTimeMS()+1000;
  934. while ( isRecvFromLoopThreadActive.GetValue()>0 && RakNet::GetTimeMS()<timeout )
  935. {
  936. RakSleep(30);
  937. }
  938. }
  939. */
  940. DerefAllSockets();
  941. ClearBufferedCommands();
  942. ClearBufferedPackets();
  943. ClearSocketQueryOutput();
  944. bytesSentPerSecond = bytesReceivedPerSecond = 0;
  945. ClearRequestedConnectionList();
  946. // Clear out the reliability layer list in case we want to reallocate it in a successive call to Init.
  947. RemoteSystemStruct * temp = remoteSystemList;
  948. remoteSystemList = 0;
  949. RakNet::OP_DELETE_ARRAY(temp, _FILE_AND_LINE_);
  950. RakNet::OP_DELETE_ARRAY(activeSystemList, _FILE_AND_LINE_);
  951. activeSystemList=0;
  952. ClearRemoteSystemLookup();
  953. #ifdef USE_THREADED_SEND
  954. RakNet::SendToThread::Deref();
  955. #endif
  956. ResetSendReceipt();
  957. }
  958. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  959. // Description:
  960. // Returns true if the network threads are running
  961. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  962. inline bool RakPeer::IsActive( void ) const
  963. {
  964. return endThreads == false;
  965. }
  966. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  967. // Description:
  968. // Fills the array remoteSystems with the systemAddress of all the systems we are connected to
  969. //
  970. // Parameters:
  971. // remoteSystems (out): An array of SystemAddress structures to be filled with the SystemAddresss of the systems we are connected to
  972. // - pass 0 to remoteSystems to only get the number of systems we are connected to
  973. // numberOfSystems (int, out): As input, the size of remoteSystems array. As output, the number of elements put into the array
  974. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  975. bool RakPeer::GetConnectionList( SystemAddress *remoteSystems, unsigned short *numberOfSystems ) const
  976. {
  977. if (numberOfSystems==0)
  978. return false;
  979. if ( remoteSystemList == 0 || endThreads == true )
  980. {
  981. if (numberOfSystems)
  982. *numberOfSystems=0;
  983. return false;
  984. }
  985. DataStructures::List<SystemAddress> addresses;
  986. DataStructures::List<RakNetGUID> guids;
  987. GetSystemList(addresses, guids);
  988. if (remoteSystems)
  989. {
  990. unsigned short i;
  991. for (i=0; i < *numberOfSystems && i < addresses.Size(); i++)
  992. remoteSystems[i]=addresses[i];
  993. *numberOfSystems=i;
  994. }
  995. else
  996. {
  997. *numberOfSystems=(unsigned short) addresses.Size();
  998. }
  999. return true;
  1000. }
  1001. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1002. uint32_t RakPeer::GetNextSendReceipt(void)
  1003. {
  1004. sendReceiptSerialMutex.Lock();
  1005. uint32_t retVal = sendReceiptSerial;
  1006. sendReceiptSerialMutex.Unlock();
  1007. return retVal;
  1008. }
  1009. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1010. uint32_t RakPeer::IncrementNextSendReceipt(void)
  1011. {
  1012. sendReceiptSerialMutex.Lock();
  1013. uint32_t returned = sendReceiptSerial;
  1014. if (++sendReceiptSerial==0)
  1015. sendReceiptSerial=1;
  1016. sendReceiptSerialMutex.Unlock();
  1017. return returned;
  1018. }
  1019. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1020. // Description:
  1021. // Sends a block of data to the specified system that you are connected to.
  1022. // This function only works while the client is connected (Use the Connect function).
  1023. // The first byte should be a message identifier starting at ID_USER_PACKET_ENUM
  1024. //
  1025. // Parameters:
  1026. // data: The block of data to send
  1027. // length: The size in bytes of the data to send
  1028. // bitStream: The bitstream to send
  1029. // priority: What priority level to send on.
  1030. // reliability: How reliability to send this data
  1031. // orderingChannel: When using ordered or sequenced packets, what channel to order these on.
  1032. // - Packets are only ordered relative to other packets on the same stream
  1033. // systemAddress: Who to send this packet to, or in the case of broadcasting who not to send it to. Use UNASSIGNED_SYSTEM_ADDRESS to specify none
  1034. // broadcast: True to send this packet to all connected systems. If true, then systemAddress specifies who not to send the packet to.
  1035. // Returns:
  1036. // \return 0 on bad input. Otherwise a number that identifies this message. If \a reliability is a type that returns a receipt, on a later call to Receive() you will get ID_SND_RECEIPT_ACKED or ID_SND_RECEIPT_LOSS with bytes 1-4 inclusive containing this number
  1037. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1038. uint32_t RakPeer::Send( const char *data, const int length, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, uint32_t forceReceiptNumber )
  1039. {
  1040. #ifdef _DEBUG
  1041. RakAssert( data && length > 0 );
  1042. #endif
  1043. RakAssert( !( reliability >= NUMBER_OF_RELIABILITIES || reliability < 0 ) );
  1044. RakAssert( !( priority > NUMBER_OF_PRIORITIES || priority < 0 ) );
  1045. RakAssert( !( orderingChannel >= NUMBER_OF_ORDERED_STREAMS ) );
  1046. if ( data == 0 || length < 0 )
  1047. return 0;
  1048. if ( remoteSystemList == 0 || endThreads == true )
  1049. return 0;
  1050. if ( broadcast == false && systemIdentifier.IsUndefined())
  1051. return 0;
  1052. uint32_t usedSendReceipt;
  1053. if (forceReceiptNumber!=0)
  1054. usedSendReceipt=forceReceiptNumber;
  1055. else
  1056. usedSendReceipt=IncrementNextSendReceipt();
  1057. if (broadcast==false && IsLoopbackAddress(systemIdentifier,true))
  1058. {
  1059. SendLoopback(data,length);
  1060. if (reliability>=UNRELIABLE_WITH_ACK_RECEIPT)
  1061. {
  1062. char buff[5];
  1063. buff[0]=ID_SND_RECEIPT_ACKED;
  1064. sendReceiptSerialMutex.Lock();
  1065. memcpy(buff+1, &sendReceiptSerial, 4);
  1066. sendReceiptSerialMutex.Unlock();
  1067. SendLoopback( buff, 5 );
  1068. }
  1069. return usedSendReceipt;
  1070. }
  1071. SendBuffered(data, length*8, priority, reliability, orderingChannel, systemIdentifier, broadcast, RemoteSystemStruct::NO_ACTION, usedSendReceipt);
  1072. return usedSendReceipt;
  1073. }
  1074. void RakPeer::SendLoopback( const char *data, const int length )
  1075. {
  1076. if ( data == 0 || length < 0 )
  1077. return;
  1078. Packet *packet = AllocPacket(length, _FILE_AND_LINE_);
  1079. memcpy(packet->data, data, length);
  1080. packet->systemAddress = GetLoopbackAddress();
  1081. packet->guid=myGuid;
  1082. PushBackPacket(packet, false);
  1083. }
  1084. uint32_t RakPeer::Send( const RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, uint32_t forceReceiptNumber )
  1085. {
  1086. #ifdef _DEBUG
  1087. RakAssert( bitStream->GetNumberOfBytesUsed() > 0 );
  1088. #endif
  1089. RakAssert( !( reliability >= NUMBER_OF_RELIABILITIES || reliability < 0 ) );
  1090. RakAssert( !( priority > NUMBER_OF_PRIORITIES || priority < 0 ) );
  1091. RakAssert( !( orderingChannel >= NUMBER_OF_ORDERED_STREAMS ) );
  1092. if ( bitStream->GetNumberOfBytesUsed() == 0 )
  1093. return 0;
  1094. if ( remoteSystemList == 0 || endThreads == true )
  1095. return 0;
  1096. if ( broadcast == false && systemIdentifier.IsUndefined() )
  1097. return 0;
  1098. uint32_t usedSendReceipt;
  1099. if (forceReceiptNumber!=0)
  1100. usedSendReceipt=forceReceiptNumber;
  1101. else
  1102. usedSendReceipt=IncrementNextSendReceipt();
  1103. if (broadcast==false && IsLoopbackAddress(systemIdentifier,true))
  1104. {
  1105. SendLoopback((const char*) bitStream->GetData(),bitStream->GetNumberOfBytesUsed());
  1106. if (reliability>=UNRELIABLE_WITH_ACK_RECEIPT)
  1107. {
  1108. char buff[5];
  1109. buff[0]=ID_SND_RECEIPT_ACKED;
  1110. sendReceiptSerialMutex.Lock();
  1111. memcpy(buff+1, &sendReceiptSerial,4);
  1112. sendReceiptSerialMutex.Unlock();
  1113. SendLoopback( buff, 5 );
  1114. }
  1115. return usedSendReceipt;
  1116. }
  1117. // Sends need to be buffered and processed in the update thread because the systemAddress associated with the reliability layer can change,
  1118. // from that thread, resulting in a send to the wrong player! While I could mutex the systemAddress, that is much slower than doing this
  1119. SendBuffered((const char*)bitStream->GetData(), bitStream->GetNumberOfBitsUsed(), priority, reliability, orderingChannel, systemIdentifier, broadcast, RemoteSystemStruct::NO_ACTION, usedSendReceipt);
  1120. return usedSendReceipt;
  1121. }
  1122. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1123. // Sends multiple blocks of data, concatenating them automatically.
  1124. //
  1125. // This is equivalent to:
  1126. // RakNet::BitStream bs;
  1127. // bs.WriteAlignedBytes(block1, blockLength1);
  1128. // bs.WriteAlignedBytes(block2, blockLength2);
  1129. // bs.WriteAlignedBytes(block3, blockLength3);
  1130. // Send(&bs, ...)
  1131. //
  1132. // This function only works while connected
  1133. // \param[in] data An array of pointers to blocks of data
  1134. // \param[in] lengths An array of integers indicating the length of each block of data
  1135. // \param[in] numParameters Length of the arrays data and lengths
  1136. // \param[in] priority What priority level to send on. See PacketPriority.h
  1137. // \param[in] reliability How reliability to send this data. See PacketPriority.h
  1138. // \param[in] orderingChannel When using ordered or sequenced messages, what channel to order these on. Messages are only ordered relative to other messages on the same stream
  1139. // \param[in] systemIdentifier Who to send this packet to, or in the case of broadcasting who not to send it to. Pass either a SystemAddress structure or a RakNetGUID structure. Use UNASSIGNED_SYSTEM_ADDRESS or to specify none
  1140. // \param[in] broadcast True to send this packet to all connected systems. If true, then systemAddress specifies who not to send the packet to.
  1141. // \return False if we are not connected to the specified recipient. True otherwise
  1142. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1143. uint32_t RakPeer::SendList( const char **data, const int *lengths, const int numParameters, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, uint32_t forceReceiptNumber )
  1144. {
  1145. #ifdef _DEBUG
  1146. RakAssert( data );
  1147. #endif
  1148. if ( data == 0 || lengths == 0 )
  1149. return 0;
  1150. if ( remoteSystemList == 0 || endThreads == true )
  1151. return 0;
  1152. if (numParameters==0)
  1153. return 0;
  1154. if (lengths==0)
  1155. return 0;
  1156. if ( broadcast == false && systemIdentifier.IsUndefined() )
  1157. return 0;
  1158. uint32_t usedSendReceipt;
  1159. if (forceReceiptNumber!=0)
  1160. usedSendReceipt=forceReceiptNumber;
  1161. else
  1162. usedSendReceipt=IncrementNextSendReceipt();
  1163. SendBufferedList(data, lengths, numParameters, priority, reliability, orderingChannel, systemIdentifier, broadcast, RemoteSystemStruct::NO_ACTION, usedSendReceipt);
  1164. return usedSendReceipt;
  1165. }
  1166. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1167. // Description:
  1168. // Gets a packet from the incoming packet queue. Use DeallocatePacket to deallocate the packet after you are done with it.
  1169. // Check the Packet struct at the top of CoreNetworkStructures.h for the format of the struct
  1170. //
  1171. // Returns:
  1172. // 0 if no packets are waiting to be handled, otherwise an allocated packet
  1173. // If the client is not active this will also return 0, as all waiting packets are flushed when the client is Disconnected
  1174. // This also updates all memory blocks associated with synchronized memory and distributed objects
  1175. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1176. #ifdef _MSC_VER
  1177. #pragma warning( disable : 4701 ) // warning C4701: local variable <variable name> may be used without having been initialized
  1178. #endif
  1179. Packet* RakPeer::Receive( void )
  1180. {
  1181. if ( !( IsActive() ) )
  1182. return 0;
  1183. RakNet::Packet *packet;
  1184. // Packet **threadPacket;
  1185. PluginReceiveResult pluginResult;
  1186. int offset;
  1187. unsigned int i;
  1188. // User should call RunUpdateCycle and RunRecvFromOnce to do this commented code
  1189. /*
  1190. #if RAKPEER_SINGLE_THREADED==1
  1191. RakPeer::RecvFromStruct *recvFromStruct;
  1192. for (i=0; i < socketList.Size(); i++)
  1193. {
  1194. while (1)
  1195. {
  1196. recvFromStruct=bufferedPackets.Allocate( _FILE_AND_LINE_ );
  1197. recvFromStruct->s=socketList[i]->s;
  1198. recvFromStruct->remotePortRakNetWasStartedOn_PS3=socketList[i]->remotePortRakNetWasStartedOn_PS3_PSP2;
  1199. recvFromStruct->extraSocketOptions=socketList[i]->extraSocketOptions;
  1200. SocketLayer::RecvFromBlocking(
  1201. recvFromStruct->s, this, recvFromStruct->remotePortRakNetWasStartedOn_PS3,
  1202. recvFromStruct->extraSocketOptions, recvFromStruct->data, &recvFromStruct->bytesRead, &recvFromStruct->systemAddress, &recvFromStruct->timeRead);
  1203. if (recvFromStruct->bytesRead<=0)
  1204. {
  1205. bufferedPackets.Deallocate(recvFromStruct, _FILE_AND_LINE_);
  1206. break;
  1207. }
  1208. else
  1209. {
  1210. RakAssert(recvFromStruct->systemAddress.GetPort());
  1211. bufferedPackets.Push(recvFromStruct);
  1212. }
  1213. }
  1214. }
  1215. BitStream updateBitStream( MAXIMUM_MTU_SIZE
  1216. #if LIBCAT_SECURITY==1
  1217. + cat::AuthenticatedEncryption::OVERHEAD_BYTES
  1218. #endif
  1219. );
  1220. RunUpdateCycle(0, 0, updateBitStream);
  1221. #endif
  1222. */
  1223. for (i=0; i < pluginListTS.Size(); i++)
  1224. {
  1225. pluginListTS[i]->Update();
  1226. }
  1227. for (i=0; i < pluginListNTS.Size(); i++)
  1228. {
  1229. pluginListNTS[i]->Update();
  1230. }
  1231. do
  1232. {
  1233. packetReturnMutex.Lock();
  1234. if (packetReturnQueue.IsEmpty())
  1235. packet=0;
  1236. else
  1237. packet = packetReturnQueue.Pop();
  1238. packetReturnMutex.Unlock();
  1239. if (packet==0)
  1240. return 0;
  1241. // unsigned char msgId;
  1242. if ( ( packet->length >= sizeof(unsigned char) + sizeof( RakNet::Time ) ) &&
  1243. ( (unsigned char) packet->data[ 0 ] == ID_TIMESTAMP ) )
  1244. {
  1245. offset = sizeof(unsigned char);
  1246. ShiftIncomingTimestamp( packet->data + offset, packet->systemAddress );
  1247. // msgId=packet->data[sizeof(unsigned char) + sizeof( RakNet::Time )];
  1248. }
  1249. // else
  1250. // msgId=packet->data[0];
  1251. // Some locally generated packets need to be processed by plugins, for example ID_FCM2_NEW_HOST
  1252. // The plugin itself should intercept these messages generated remotely
  1253. // if (packet->wasGeneratedLocally)
  1254. // return packet;
  1255. CallPluginCallbacks(pluginListTS, packet);
  1256. CallPluginCallbacks(pluginListNTS, packet);
  1257. for (i=0; i < pluginListTS.Size(); i++)
  1258. {
  1259. pluginResult=pluginListTS[i]->OnReceive(packet);
  1260. if (pluginResult==RR_STOP_PROCESSING_AND_DEALLOCATE)
  1261. {
  1262. DeallocatePacket( packet );
  1263. packet=0; // Will do the loop again and get another packet
  1264. break; // break out of the enclosing for
  1265. }
  1266. else if (pluginResult==RR_STOP_PROCESSING)
  1267. {
  1268. packet=0;
  1269. break;
  1270. }
  1271. }
  1272. for (i=0; i < pluginListNTS.Size(); i++)
  1273. {
  1274. pluginResult=pluginListNTS[i]->OnReceive(packet);
  1275. if (pluginResult==RR_STOP_PROCESSING_AND_DEALLOCATE)
  1276. {
  1277. DeallocatePacket( packet );
  1278. packet=0; // Will do the loop again and get another packet
  1279. break; // break out of the enclosing for
  1280. }
  1281. else if (pluginResult==RR_STOP_PROCESSING)
  1282. {
  1283. packet=0;
  1284. break;
  1285. }
  1286. }
  1287. } while(packet==0);
  1288. #ifdef _DEBUG
  1289. RakAssert( packet->data );
  1290. #endif
  1291. return packet;
  1292. }
  1293. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1294. // Description:
  1295. // Call this to deallocate a packet returned by Receive
  1296. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1297. void RakPeer::DeallocatePacket( Packet *packet )
  1298. {
  1299. if ( packet == 0 )
  1300. return;
  1301. if (packet->deleteData)
  1302. {
  1303. rakFree_Ex(packet->data, _FILE_AND_LINE_ );
  1304. packet->~Packet();
  1305. packetAllocationPoolMutex.Lock();
  1306. packetAllocationPool.Release(packet,_FILE_AND_LINE_);
  1307. packetAllocationPoolMutex.Unlock();
  1308. }
  1309. else
  1310. {
  1311. rakFree_Ex(packet, _FILE_AND_LINE_ );
  1312. }
  1313. }
  1314. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1315. // Description:
  1316. // Return the total number of connections we are allowed
  1317. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1318. unsigned int RakPeer::GetMaximumNumberOfPeers( void ) const
  1319. {
  1320. return maximumNumberOfPeers;
  1321. }
  1322. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1323. // Description:
  1324. // Close the connection to another host (if we initiated the connection it will disconnect, if they did it will kick them out).
  1325. //
  1326. // Parameters:
  1327. // target: Which connection to close
  1328. // sendDisconnectionNotification: True to send ID_DISCONNECTION_NOTIFICATION to the recipient. False to close it silently.
  1329. // channel: If blockDuration > 0, the disconnect packet will be sent on this channel
  1330. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1331. void RakPeer::CloseConnection( const AddressOrGUID target, bool sendDisconnectionNotification, unsigned char orderingChannel, PacketPriority disconnectionNotificationPriority )
  1332. {
  1333. /*
  1334. // This only be called from the user thread, for the user shutting down.
  1335. // From the network thread, this should occur because of ID_DISCONNECTION_NOTIFICATION and ID_CONNECTION_LOST
  1336. unsigned j;
  1337. for (j=0; j < messageHandlerList.Size(); j++)
  1338. {
  1339. messageHandlerList[j]->OnClosedConnection(
  1340. target.systemAddress==UNASSIGNED_SYSTEM_ADDRESS ? GetSystemAddressFromGuid(target.rakNetGuid) : target.systemAddress,
  1341. target.rakNetGuid==UNASSIGNED_RAKNET_GUID ? GetGuidFromSystemAddress(target.systemAddress) : target.rakNetGuid,
  1342. LCR_CLOSED_BY_USER);
  1343. }
  1344. */
  1345. CloseConnectionInternal(target, sendDisconnectionNotification, false, orderingChannel, disconnectionNotificationPriority);
  1346. // 12/14/09 Return ID_CONNECTION_LOST when calling CloseConnection with sendDisconnectionNotification==false, elsewise it is never returned
  1347. if (sendDisconnectionNotification==false && GetConnectionState(target)==IS_CONNECTED)
  1348. {
  1349. Packet *packet=AllocPacket(sizeof( char ), _FILE_AND_LINE_);
  1350. packet->data[ 0 ] = ID_CONNECTION_LOST; // DeadConnection
  1351. packet->guid = target.rakNetGuid==UNASSIGNED_RAKNET_GUID ? GetGuidFromSystemAddress(target.systemAddress) : target.rakNetGuid;
  1352. packet->systemAddress = target.systemAddress==UNASSIGNED_SYSTEM_ADDRESS ? GetSystemAddressFromGuid(target.rakNetGuid) : target.systemAddress;
  1353. packet->systemAddress.systemIndex = (SystemIndex) GetIndexFromSystemAddress(packet->systemAddress);
  1354. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  1355. packet->wasGeneratedLocally=true; // else processed twice
  1356. AddPacketToProducer(packet);
  1357. }
  1358. }
  1359. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1360. // Cancel a pending connection attempt
  1361. // If we are already connected, the connection stays open
  1362. // \param[in] target Which system to cancel
  1363. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1364. void RakPeer::CancelConnectionAttempt( const SystemAddress target )
  1365. {
  1366. unsigned int i;
  1367. // Cancel pending connection attempt, if there is one
  1368. i=0;
  1369. requestedConnectionQueueMutex.Lock();
  1370. while (i < requestedConnectionQueue.Size())
  1371. {
  1372. if (requestedConnectionQueue[i]->systemAddress==target)
  1373. {
  1374. #if LIBCAT_SECURITY==1
  1375. CAT_AUDIT_PRINTF("AUDIT: Deleting requestedConnectionQueue %i client_handshake %x\n", i, requestedConnectionQueue[ i ]->client_handshake);
  1376. RakNet::OP_DELETE(requestedConnectionQueue[i]->client_handshake, _FILE_AND_LINE_ );
  1377. #endif
  1378. RakNet::OP_DELETE(requestedConnectionQueue[i], _FILE_AND_LINE_ );
  1379. requestedConnectionQueue.RemoveAtIndex(i);
  1380. break;
  1381. }
  1382. else
  1383. i++;
  1384. }
  1385. requestedConnectionQueueMutex.Unlock();
  1386. }
  1387. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1388. #ifdef _MSC_VER
  1389. #pragma warning( disable : 4702 ) // warning C4702: unreachable code
  1390. #endif
  1391. ConnectionState RakPeer::GetConnectionState(const AddressOrGUID systemIdentifier)
  1392. {
  1393. if (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS)
  1394. {
  1395. unsigned int i=0;
  1396. requestedConnectionQueueMutex.Lock();
  1397. for (; i < requestedConnectionQueue.Size(); i++)
  1398. {
  1399. if (requestedConnectionQueue[i]->systemAddress==systemIdentifier.systemAddress)
  1400. {
  1401. requestedConnectionQueueMutex.Unlock();
  1402. return IS_PENDING;
  1403. }
  1404. }
  1405. requestedConnectionQueueMutex.Unlock();
  1406. }
  1407. int index;
  1408. if (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS)
  1409. {
  1410. index = GetIndexFromSystemAddress(systemIdentifier.systemAddress, false);
  1411. }
  1412. else
  1413. {
  1414. index = GetIndexFromGuid(systemIdentifier.rakNetGuid);
  1415. }
  1416. if (index==-1)
  1417. return IS_NOT_CONNECTED;
  1418. if (remoteSystemList[index].isActive==false)
  1419. return IS_DISCONNECTED;
  1420. switch (remoteSystemList[index].connectMode)
  1421. {
  1422. case RemoteSystemStruct::DISCONNECT_ASAP:
  1423. return IS_DISCONNECTING;
  1424. case RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY:
  1425. return IS_SILENTLY_DISCONNECTING;
  1426. case RemoteSystemStruct::DISCONNECT_ON_NO_ACK:
  1427. return IS_DISCONNECTING;
  1428. case RemoteSystemStruct::REQUESTED_CONNECTION:
  1429. return IS_CONNECTING;
  1430. case RemoteSystemStruct::HANDLING_CONNECTION_REQUEST:
  1431. return IS_CONNECTING;
  1432. case RemoteSystemStruct::UNVERIFIED_SENDER:
  1433. return IS_CONNECTING;
  1434. case RemoteSystemStruct::CONNECTED:
  1435. return IS_CONNECTED;
  1436. default:
  1437. return IS_NOT_CONNECTED;
  1438. }
  1439. return IS_NOT_CONNECTED;
  1440. }
  1441. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1442. // Description:
  1443. // Given a systemAddress, returns an index from 0 to the maximum number of players allowed - 1.
  1444. //
  1445. // Parameters
  1446. // systemAddress - The systemAddress to search for
  1447. //
  1448. // Returns
  1449. // An integer from 0 to the maximum number of peers -1, or -1 if that player is not found
  1450. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1451. int RakPeer::GetIndexFromSystemAddress( const SystemAddress systemAddress ) const
  1452. {
  1453. return GetIndexFromSystemAddress(systemAddress, false);
  1454. }
  1455. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1456. // Description:
  1457. // This function is only useful for looping through all players.
  1458. //
  1459. // Parameters
  1460. // index - an integer between 0 and the maximum number of players allowed - 1.
  1461. //
  1462. // Returns
  1463. // A valid systemAddress or UNASSIGNED_SYSTEM_ADDRESS if no such player at that index
  1464. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1465. SystemAddress RakPeer::GetSystemAddressFromIndex( unsigned int index )
  1466. {
  1467. // remoteSystemList in user thread
  1468. //if ( index >= 0 && index < remoteSystemListSize )
  1469. if ( index < maximumNumberOfPeers )
  1470. if (remoteSystemList[index].isActive && remoteSystemList[ index ].connectMode==RakPeer::RemoteSystemStruct::CONNECTED) // Don't give the user players that aren't fully connected, since sends will fail
  1471. return remoteSystemList[ index ].systemAddress;
  1472. return UNASSIGNED_SYSTEM_ADDRESS;
  1473. }
  1474. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1475. // Same as GetSystemAddressFromIndex but returns RakNetGUID
  1476. // \param[in] index Index should range between 0 and the maximum number of players allowed - 1.
  1477. // \return The RakNetGUID
  1478. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1479. RakNetGUID RakPeer::GetGUIDFromIndex( unsigned int index )
  1480. {
  1481. // remoteSystemList in user thread
  1482. //if ( index >= 0 && index < remoteSystemListSize )
  1483. if ( index < maximumNumberOfPeers )
  1484. if (remoteSystemList[index].isActive && remoteSystemList[ index ].connectMode==RakPeer::RemoteSystemStruct::CONNECTED) // Don't give the user players that aren't fully connected, since sends will fail
  1485. return remoteSystemList[ index ].guid;
  1486. return UNASSIGNED_RAKNET_GUID;
  1487. }
  1488. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1489. // Same as calling GetSystemAddressFromIndex and GetGUIDFromIndex for all systems, but more efficient
  1490. // Indices match each other, so \a addresses[0] and \a guids[0] refer to the same system
  1491. // \param[out] addresses All system addresses. Size of the list is the number of connections. Size of the list will match the size of the \a guids list.
  1492. // \param[out] guids All guids. Size of the list is the number of connections. Size of the list will match the size of the \a addresses list.
  1493. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1494. void RakPeer::GetSystemList(DataStructures::List<SystemAddress> &addresses, DataStructures::List<RakNetGUID> &guids) const
  1495. {
  1496. addresses.Clear(false, _FILE_AND_LINE_);
  1497. guids.Clear(false, _FILE_AND_LINE_);
  1498. if ( remoteSystemList == 0 || endThreads == true )
  1499. return;
  1500. unsigned int i;
  1501. for (i=0; i < activeSystemListSize; i++)
  1502. {
  1503. if ((activeSystemList[i])->isActive &&
  1504. (activeSystemList[i])->connectMode==RakPeer::RemoteSystemStruct::CONNECTED)
  1505. {
  1506. addresses.Push((activeSystemList[i])->systemAddress, _FILE_AND_LINE_ );
  1507. guids.Push((activeSystemList[i])->guid, _FILE_AND_LINE_ );
  1508. }
  1509. }
  1510. }
  1511. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1512. // Description:
  1513. // Bans an IP from connecting. Banned IPs persist between connections.
  1514. //
  1515. // Parameters
  1516. // IP - Dotted IP address. Can use * as a wildcard, such as 128.0.0.* will ban
  1517. // All IP addresses starting with 128.0.0
  1518. // milliseconds - how many ms for a temporary ban. Use 0 for a permanent ban
  1519. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1520. void RakPeer::AddToBanList( const char *IP, RakNet::TimeMS milliseconds )
  1521. {
  1522. unsigned index;
  1523. RakNet::TimeMS time = RakNet::GetTimeMS();
  1524. if ( IP == 0 || IP[ 0 ] == 0 || strlen( IP ) > 15 )
  1525. return ;
  1526. // If this guy is already in the ban list, do nothing
  1527. index = 0;
  1528. banListMutex.Lock();
  1529. for ( ; index < banList.Size(); index++ )
  1530. {
  1531. if ( strcmp( IP, banList[ index ]->IP ) == 0 )
  1532. {
  1533. // Already in the ban list. Just update the time
  1534. if (milliseconds==0)
  1535. banList[ index ]->timeout=0; // Infinite
  1536. else
  1537. banList[ index ]->timeout=time+milliseconds;
  1538. banListMutex.Unlock();
  1539. return;
  1540. }
  1541. }
  1542. banListMutex.Unlock();
  1543. BanStruct *banStruct = RakNet::OP_NEW<BanStruct>( _FILE_AND_LINE_ );
  1544. banStruct->IP = (char*) rakMalloc_Ex( 16, _FILE_AND_LINE_ );
  1545. if (milliseconds==0)
  1546. banStruct->timeout=0; // Infinite
  1547. else
  1548. banStruct->timeout=time+milliseconds;
  1549. strcpy( banStruct->IP, IP );
  1550. banListMutex.Lock();
  1551. banList.Insert( banStruct, _FILE_AND_LINE_ );
  1552. banListMutex.Unlock();
  1553. }
  1554. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1555. // Description:
  1556. // Allows a previously banned IP to connect.
  1557. //
  1558. // Parameters
  1559. // IP - Dotted IP address. Can use * as a wildcard, such as 128.0.0.* will ban
  1560. // All IP addresses starting with 128.0.0
  1561. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1562. void RakPeer::RemoveFromBanList( const char *IP )
  1563. {
  1564. unsigned index;
  1565. BanStruct *temp;
  1566. if ( IP == 0 || IP[ 0 ] == 0 || strlen( IP ) > 15 )
  1567. return ;
  1568. index = 0;
  1569. temp=0;
  1570. banListMutex.Lock();
  1571. for ( ; index < banList.Size(); index++ )
  1572. {
  1573. if ( strcmp( IP, banList[ index ]->IP ) == 0 )
  1574. {
  1575. temp = banList[ index ];
  1576. banList[ index ] = banList[ banList.Size() - 1 ];
  1577. banList.RemoveAtIndex( banList.Size() - 1 );
  1578. break;
  1579. }
  1580. }
  1581. banListMutex.Unlock();
  1582. if (temp)
  1583. {
  1584. rakFree_Ex(temp->IP, _FILE_AND_LINE_ );
  1585. RakNet::OP_DELETE(temp, _FILE_AND_LINE_);
  1586. }
  1587. }
  1588. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1589. // Description:
  1590. // Allows all previously banned IPs to connect.
  1591. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1592. void RakPeer::ClearBanList( void )
  1593. {
  1594. unsigned index;
  1595. index = 0;
  1596. banListMutex.Lock();
  1597. for ( ; index < banList.Size(); index++ )
  1598. {
  1599. rakFree_Ex(banList[ index ]->IP, _FILE_AND_LINE_ );
  1600. RakNet::OP_DELETE(banList[ index ], _FILE_AND_LINE_);
  1601. }
  1602. banList.Clear(false, _FILE_AND_LINE_);
  1603. banListMutex.Unlock();
  1604. }
  1605. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1606. void RakPeer::SetLimitIPConnectionFrequency(bool b)
  1607. {
  1608. limitConnectionFrequencyFromTheSameIP=b;
  1609. }
  1610. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1611. // Description:
  1612. // Determines if a particular IP is banned.
  1613. //
  1614. // Parameters
  1615. // IP - Complete dotted IP address
  1616. //
  1617. // Returns
  1618. // True if IP matches any IPs in the ban list, accounting for any wildcards.
  1619. // False otherwise.
  1620. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1621. bool RakPeer::IsBanned( const char *IP )
  1622. {
  1623. unsigned banListIndex, characterIndex;
  1624. RakNet::TimeMS time;
  1625. BanStruct *temp;
  1626. if ( IP == 0 || IP[ 0 ] == 0 || strlen( IP ) > 15 )
  1627. return false;
  1628. banListIndex = 0;
  1629. if ( banList.Size() == 0 )
  1630. return false; // Skip the mutex if possible
  1631. time = RakNet::GetTimeMS();
  1632. banListMutex.Lock();
  1633. while ( banListIndex < banList.Size() )
  1634. {
  1635. if (banList[ banListIndex ]->timeout>0 && banList[ banListIndex ]->timeout<time)
  1636. {
  1637. // Delete expired ban
  1638. temp = banList[ banListIndex ];
  1639. banList[ banListIndex ] = banList[ banList.Size() - 1 ];
  1640. banList.RemoveAtIndex( banList.Size() - 1 );
  1641. rakFree_Ex(temp->IP, _FILE_AND_LINE_ );
  1642. RakNet::OP_DELETE(temp, _FILE_AND_LINE_);
  1643. }
  1644. else
  1645. {
  1646. characterIndex = 0;
  1647. #ifdef _MSC_VER
  1648. #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
  1649. #endif
  1650. while ( true )
  1651. {
  1652. if ( banList[ banListIndex ]->IP[ characterIndex ] == IP[ characterIndex ] )
  1653. {
  1654. // Equal characters
  1655. if ( IP[ characterIndex ] == 0 )
  1656. {
  1657. banListMutex.Unlock();
  1658. // End of the string and the strings match
  1659. return true;
  1660. }
  1661. characterIndex++;
  1662. }
  1663. else
  1664. {
  1665. if ( banList[ banListIndex ]->IP[ characterIndex ] == 0 || IP[ characterIndex ] == 0 )
  1666. {
  1667. // End of one of the strings
  1668. break;
  1669. }
  1670. // Characters do not match
  1671. if ( banList[ banListIndex ]->IP[ characterIndex ] == '*' )
  1672. {
  1673. banListMutex.Unlock();
  1674. // Domain is banned.
  1675. return true;
  1676. }
  1677. // Characters do not match and it is not a *
  1678. break;
  1679. }
  1680. }
  1681. banListIndex++;
  1682. }
  1683. }
  1684. banListMutex.Unlock();
  1685. // No match found.
  1686. return false;
  1687. }
  1688. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1689. // Description:
  1690. // Send a ping to the specified connected system.
  1691. //
  1692. // Parameters:
  1693. // target - who to ping
  1694. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1695. void RakPeer::Ping( const SystemAddress target )
  1696. {
  1697. PingInternal(target, false, UNRELIABLE);
  1698. }
  1699. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1700. // Description:
  1701. // Send a ping to the specified unconnected system.
  1702. // The remote system, if it is Initialized, will respond with ID_UNCONNECTED_PONG.
  1703. // The final ping time will be encoded in the following sizeof(RakNet::TimeMS) bytes. (Default is 4 bytes - See __GET_TIME_64BIT in RakNetTypes.h
  1704. //
  1705. // Parameters:
  1706. // host: Either a dotted IP address or a domain name. Can be 255.255.255.255 for LAN broadcast.
  1707. // remotePort: Which port to connect to on the remote machine.
  1708. // onlyReplyOnAcceptingConnections: Only request a reply if the remote system has open connections
  1709. // connectionSocketIndex Index into the array of socket descriptors passed to socketDescriptors in RakPeer::Startup() to send on.
  1710. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1711. bool RakPeer::Ping( const char* host, unsigned short remotePort, bool onlyReplyOnAcceptingConnections, unsigned connectionSocketIndex )
  1712. {
  1713. if ( host == 0 )
  1714. return false;
  1715. // If this assert hits then Startup wasn't called or the call failed.
  1716. RakAssert(connectionSocketIndex < socketList.Size());
  1717. // if ( IsActive() == false )
  1718. // return;
  1719. RakNet::BitStream bitStream( sizeof(unsigned char) + sizeof(RakNet::Time) );
  1720. if ( onlyReplyOnAcceptingConnections )
  1721. bitStream.Write((MessageID)ID_UNCONNECTED_PING_OPEN_CONNECTIONS);
  1722. else
  1723. bitStream.Write((MessageID)ID_UNCONNECTED_PING);
  1724. bitStream.Write(RakNet::GetTime());
  1725. bitStream.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  1726. bitStream.Write(GetMyGUID());
  1727. // No timestamp for 255.255.255.255
  1728. unsigned int realIndex = GetRakNetSocketFromUserConnectionSocketIndex(connectionSocketIndex);
  1729. /*
  1730. SystemAddress systemAddress;
  1731. systemAddress.FromStringExplicitPort(host,remotePort, socketList[realIndex]->GetBoundAddress().GetIPVersion());
  1732. systemAddress.FixForIPVersion(socketList[realIndex]->GetBoundAddress());
  1733. unsigned i;
  1734. for (i=0; i < pluginListNTS.Size(); i++)
  1735. pluginListNTS[i]->OnDirectSocketSend((const char*)bitStream.GetData(), bitStream.GetNumberOfBitsUsed(), systemAddress);
  1736. SocketLayer::SendTo( socketList[realIndex], (const char*)bitStream.GetData(), (int) bitStream.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  1737. */
  1738. RNS2_SendParameters bsp;
  1739. bsp.data = (char*) bitStream.GetData() ;
  1740. bsp.length = bitStream.GetNumberOfBytesUsed();
  1741. bsp.systemAddress.FromStringExplicitPort(host,remotePort, socketList[realIndex]->GetBoundAddress().GetIPVersion());
  1742. if (bsp.systemAddress==UNASSIGNED_SYSTEM_ADDRESS)
  1743. return false;
  1744. bsp.systemAddress.FixForIPVersion(socketList[realIndex]->GetBoundAddress());
  1745. unsigned i;
  1746. for (i=0; i < pluginListNTS.Size(); i++)
  1747. pluginListNTS[i]->OnDirectSocketSend((const char*)bitStream.GetData(), bitStream.GetNumberOfBitsUsed(), bsp.systemAddress);
  1748. socketList[realIndex]->Send(&bsp, _FILE_AND_LINE_);
  1749. return true;
  1750. }
  1751. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1752. // Description:
  1753. // Returns the average of all ping times read for a specified target
  1754. //
  1755. // Parameters:
  1756. // target - whose time to read
  1757. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1758. int RakPeer::GetAveragePing( const AddressOrGUID systemIdentifier )
  1759. {
  1760. int sum, quantity;
  1761. RemoteSystemStruct *remoteSystem = GetRemoteSystem( systemIdentifier, false, false );
  1762. if ( remoteSystem == 0 )
  1763. return -1;
  1764. for ( sum = 0, quantity = 0; quantity < PING_TIMES_ARRAY_SIZE; quantity++ )
  1765. {
  1766. if ( remoteSystem->pingAndClockDifferential[ quantity ].pingTime == 65535 )
  1767. break;
  1768. else
  1769. sum += remoteSystem->pingAndClockDifferential[ quantity ].pingTime;
  1770. }
  1771. if ( quantity > 0 )
  1772. return sum / quantity;
  1773. else
  1774. return -1;
  1775. }
  1776. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1777. // Description:
  1778. // Returns the last ping time read for the specific player or -1 if none read yet
  1779. //
  1780. // Parameters:
  1781. // target - whose time to read
  1782. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1783. int RakPeer::GetLastPing( const AddressOrGUID systemIdentifier ) const
  1784. {
  1785. RemoteSystemStruct * remoteSystem = GetRemoteSystem( systemIdentifier, false, false );
  1786. if ( remoteSystem == 0 )
  1787. return -1;
  1788. // return (int)(remoteSystem->reliabilityLayer.GetAckPing()/(RakNet::TimeUS)1000);
  1789. if ( remoteSystem->pingAndClockDifferentialWriteIndex == 0 )
  1790. return remoteSystem->pingAndClockDifferential[ PING_TIMES_ARRAY_SIZE - 1 ].pingTime;
  1791. else
  1792. return remoteSystem->pingAndClockDifferential[ remoteSystem->pingAndClockDifferentialWriteIndex - 1 ].pingTime;
  1793. }
  1794. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1795. // Description:
  1796. // Returns the lowest ping time read or -1 if none read yet
  1797. //
  1798. // Parameters:
  1799. // target - whose time to read
  1800. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1801. int RakPeer::GetLowestPing( const AddressOrGUID systemIdentifier ) const
  1802. {
  1803. RemoteSystemStruct * remoteSystem = GetRemoteSystem( systemIdentifier, false, false );
  1804. if ( remoteSystem == 0 )
  1805. return -1;
  1806. return remoteSystem->lowestPing;
  1807. }
  1808. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1809. // Description:
  1810. // Ping the remote systems every so often. This is off by default
  1811. // This will work anytime
  1812. //
  1813. // Parameters:
  1814. // doPing - True to start occasional pings. False to stop them.
  1815. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1816. void RakPeer::SetOccasionalPing( bool doPing )
  1817. {
  1818. occasionalPing = doPing;
  1819. }
  1820. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1821. /// Return the clock difference between your system and the specified system
  1822. /// Subtract the time from a time returned by the remote system to get that time relative to your own system
  1823. /// Returns 0 if the system is unknown
  1824. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1825. RakNet::Time RakPeer::GetClockDifferential( const AddressOrGUID systemIdentifier )
  1826. {
  1827. RemoteSystemStruct *remoteSystem = GetRemoteSystem(systemIdentifier, false, false);
  1828. if (remoteSystem == 0)
  1829. return 0;
  1830. return GetClockDifferentialInt(remoteSystem);
  1831. }
  1832. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1833. RakNet::Time RakPeer::GetClockDifferentialInt(RemoteSystemStruct *remoteSystem) const
  1834. {
  1835. int counter, lowestPingSoFar;
  1836. RakNet::Time clockDifferential;
  1837. lowestPingSoFar = 65535;
  1838. clockDifferential = 0;
  1839. for ( counter = 0; counter < PING_TIMES_ARRAY_SIZE; counter++ )
  1840. {
  1841. if ( remoteSystem->pingAndClockDifferential[ counter ].pingTime == 65535 )
  1842. break;
  1843. if ( remoteSystem->pingAndClockDifferential[ counter ].pingTime < lowestPingSoFar )
  1844. {
  1845. clockDifferential = remoteSystem->pingAndClockDifferential[ counter ].clockDifferential;
  1846. lowestPingSoFar = remoteSystem->pingAndClockDifferential[ counter ].pingTime;
  1847. }
  1848. }
  1849. return clockDifferential;
  1850. }
  1851. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1852. // Description:
  1853. // Length should be under 400 bytes, as a security measure against flood attacks
  1854. // Sets the data to send with an (LAN server discovery) /(offline ping) response
  1855. // See the Ping sample project for how this is used.
  1856. // data: a block of data to store, or 0 for none
  1857. // length: The length of data in bytes, or 0 for none
  1858. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1859. void RakPeer::SetOfflinePingResponse( const char *data, const unsigned int length )
  1860. {
  1861. RakAssert(length < 400);
  1862. rakPeerMutexes[ offlinePingResponse_Mutex ].Lock();
  1863. offlinePingResponse.Reset();
  1864. if ( data && length > 0 )
  1865. offlinePingResponse.Write( data, length );
  1866. rakPeerMutexes[ offlinePingResponse_Mutex ].Unlock();
  1867. }
  1868. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1869. // Returns pointers to a copy of the data passed to SetOfflinePingResponse
  1870. // \param[out] data A pointer to a copy of the data passed to \a SetOfflinePingResponse()
  1871. // \param[out] length A pointer filled in with the length parameter passed to SetOfflinePingResponse()
  1872. // \sa SetOfflinePingResponse
  1873. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1874. void RakPeer::GetOfflinePingResponse( char **data, unsigned int *length )
  1875. {
  1876. rakPeerMutexes[ offlinePingResponse_Mutex ].Lock();
  1877. *data = (char*) offlinePingResponse.GetData();
  1878. *length = (int) offlinePingResponse.GetNumberOfBytesUsed();
  1879. rakPeerMutexes[ offlinePingResponse_Mutex ].Unlock();
  1880. }
  1881. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1882. // Description:
  1883. // Return the unique SystemAddress that represents you on the the network
  1884. // Note that unlike in previous versions, this is a struct and is not sequential
  1885. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1886. SystemAddress RakPeer::GetInternalID( const SystemAddress systemAddress, const int index ) const
  1887. {
  1888. if (systemAddress==UNASSIGNED_SYSTEM_ADDRESS)
  1889. {
  1890. return ipList[index];
  1891. }
  1892. else
  1893. {
  1894. // SystemAddress returnValue;
  1895. RemoteSystemStruct * remoteSystem = GetRemoteSystemFromSystemAddress( systemAddress, false, true );
  1896. if (remoteSystem==0)
  1897. return UNASSIGNED_SYSTEM_ADDRESS;
  1898. return remoteSystem->theirInternalSystemAddress[index];
  1899. /*
  1900. sockaddr_in sa;
  1901. socklen_t len = sizeof(sa);
  1902. if (getsockname__(connectionSockets[remoteSystem->connectionSocketIndex], (sockaddr*)&sa, &len)!=0)
  1903. return UNASSIGNED_SYSTEM_ADDRESS;
  1904. returnValue.port=ntohs(sa.sin_port);
  1905. returnValue.binaryAddress=sa.sin_addr.s_addr;
  1906. return returnValue;
  1907. */
  1908. }
  1909. }
  1910. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1911. /// \brief Sets your internal IP address, for platforms that do not support reading it, or to override a value
  1912. /// \param[in] systemAddress. The address to set. Use SystemAddress::FromString() if you want to use a dotted string
  1913. /// \param[in] index When you have multiple internal IDs, which index to set?
  1914. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1915. void RakPeer::SetInternalID(SystemAddress systemAddress, int index)
  1916. {
  1917. RakAssert(index >=0 && index < MAXIMUM_NUMBER_OF_INTERNAL_IDS);
  1918. ipList[index]=systemAddress;
  1919. }
  1920. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1921. // Description:
  1922. // Return the unique address identifier that represents you on the the network and is based on your external
  1923. // IP / port (the IP / port the specified player uses to communicate with you)
  1924. // Note that unlike in previous versions, this is a struct and is not sequential
  1925. //
  1926. // Parameters:
  1927. // target: Which remote system you are referring to for your external ID
  1928. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1929. SystemAddress RakPeer::GetExternalID( const SystemAddress target ) const
  1930. {
  1931. unsigned i;
  1932. SystemAddress inactiveExternalId;
  1933. inactiveExternalId=UNASSIGNED_SYSTEM_ADDRESS;
  1934. if (target==UNASSIGNED_SYSTEM_ADDRESS)
  1935. return firstExternalID;
  1936. // First check for active connection with this systemAddress
  1937. for ( i = 0; i < maximumNumberOfPeers; i++ )
  1938. {
  1939. if (remoteSystemList[ i ].systemAddress == target )
  1940. {
  1941. if ( remoteSystemList[ i ].isActive )
  1942. return remoteSystemList[ i ].myExternalSystemAddress;
  1943. else if (remoteSystemList[ i ].myExternalSystemAddress!=UNASSIGNED_SYSTEM_ADDRESS)
  1944. inactiveExternalId=remoteSystemList[ i ].myExternalSystemAddress;
  1945. }
  1946. }
  1947. return inactiveExternalId;
  1948. }
  1949. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1950. const RakNetGUID RakPeer::GetMyGUID(void) const
  1951. {
  1952. return myGuid;
  1953. }
  1954. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1955. SystemAddress RakPeer::GetMyBoundAddress(const int socketIndex)
  1956. {
  1957. DataStructures::List<RakNetSocket2* > sockets;
  1958. GetSockets( sockets );
  1959. if (sockets.Size()>0)
  1960. return sockets[socketIndex]->GetBoundAddress();
  1961. else
  1962. return UNASSIGNED_SYSTEM_ADDRESS;
  1963. }
  1964. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1965. const RakNetGUID& RakPeer::GetGuidFromSystemAddress( const SystemAddress input ) const
  1966. {
  1967. if (input==UNASSIGNED_SYSTEM_ADDRESS)
  1968. return myGuid;
  1969. if (input.systemIndex!=(SystemIndex)-1 && input.systemIndex<maximumNumberOfPeers && remoteSystemList[ input.systemIndex ].systemAddress == input)
  1970. return remoteSystemList[ input.systemIndex ].guid;
  1971. unsigned int i;
  1972. for ( i = 0; i < maximumNumberOfPeers; i++ )
  1973. {
  1974. if (remoteSystemList[ i ].systemAddress == input )
  1975. {
  1976. // Set the systemIndex so future lookups will be fast
  1977. remoteSystemList[i].guid.systemIndex = (SystemIndex) i;
  1978. return remoteSystemList[ i ].guid;
  1979. }
  1980. }
  1981. return UNASSIGNED_RAKNET_GUID;
  1982. }
  1983. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1984. unsigned int RakPeer::GetSystemIndexFromGuid( const RakNetGUID input ) const
  1985. {
  1986. if (input==UNASSIGNED_RAKNET_GUID)
  1987. return (unsigned int) -1;
  1988. if (input==myGuid)
  1989. return (unsigned int) -1;
  1990. if (input.systemIndex!=(SystemIndex)-1 && input.systemIndex<maximumNumberOfPeers && remoteSystemList[ input.systemIndex ].guid == input)
  1991. return input.systemIndex;
  1992. unsigned int i;
  1993. for ( i = 0; i < maximumNumberOfPeers; i++ )
  1994. {
  1995. if (remoteSystemList[ i ].guid == input )
  1996. {
  1997. // Set the systemIndex so future lookups will be fast
  1998. remoteSystemList[i].guid.systemIndex = (SystemIndex) i;
  1999. return i;
  2000. }
  2001. }
  2002. return (unsigned int) -1;
  2003. }
  2004. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2005. SystemAddress RakPeer::GetSystemAddressFromGuid( const RakNetGUID input ) const
  2006. {
  2007. if (input==UNASSIGNED_RAKNET_GUID)
  2008. return UNASSIGNED_SYSTEM_ADDRESS;
  2009. if (input==myGuid)
  2010. return GetInternalID(UNASSIGNED_SYSTEM_ADDRESS);
  2011. if (input.systemIndex!=(SystemIndex)-1 && input.systemIndex<maximumNumberOfPeers && remoteSystemList[ input.systemIndex ].guid == input)
  2012. return remoteSystemList[ input.systemIndex ].systemAddress;
  2013. unsigned int i;
  2014. for ( i = 0; i < maximumNumberOfPeers; i++ )
  2015. {
  2016. if (remoteSystemList[ i ].guid == input )
  2017. {
  2018. // Set the systemIndex so future lookups will be fast
  2019. remoteSystemList[i].guid.systemIndex = (SystemIndex) i;
  2020. return remoteSystemList[ i ].systemAddress;
  2021. }
  2022. }
  2023. return UNASSIGNED_SYSTEM_ADDRESS;
  2024. }
  2025. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2026. bool RakPeer::GetClientPublicKeyFromSystemAddress( const SystemAddress input, char *client_public_key ) const
  2027. {
  2028. #if LIBCAT_SECURITY == 1
  2029. if (input == UNASSIGNED_SYSTEM_ADDRESS)
  2030. return false;
  2031. char *copy_source = 0;
  2032. if (input.systemIndex!=(SystemIndex)-1 && input.systemIndex<maximumNumberOfPeers && remoteSystemList[ input.systemIndex ].systemAddress == input)
  2033. {
  2034. copy_source = remoteSystemList[ input.systemIndex ].client_public_key;
  2035. }
  2036. else
  2037. {
  2038. for ( unsigned int i = 0; i < maximumNumberOfPeers; i++ )
  2039. {
  2040. if (remoteSystemList[ i ].systemAddress == input )
  2041. {
  2042. copy_source = remoteSystemList[ i ].client_public_key;
  2043. break;
  2044. }
  2045. }
  2046. }
  2047. if (copy_source)
  2048. {
  2049. // Verify that at least one byte in the public key is non-zero to indicate that the key was received
  2050. for (int ii = 0; ii < cat::EasyHandshake::PUBLIC_KEY_BYTES; ++ii)
  2051. {
  2052. if (copy_source[ii] != 0)
  2053. {
  2054. memcpy(client_public_key, copy_source, cat::EasyHandshake::PUBLIC_KEY_BYTES);
  2055. return true;
  2056. }
  2057. }
  2058. }
  2059. #else
  2060. (void) input;
  2061. (void) client_public_key;
  2062. #endif
  2063. return false;
  2064. }
  2065. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2066. // Set the time, in MS, to use before considering ourselves disconnected after not being able to deliver a reliable packet
  2067. // \param[in] time Time, in MS
  2068. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2069. void RakPeer::SetTimeoutTime( RakNet::TimeMS timeMS, const SystemAddress target )
  2070. {
  2071. if (target==UNASSIGNED_SYSTEM_ADDRESS)
  2072. {
  2073. defaultTimeoutTime=timeMS;
  2074. unsigned i;
  2075. for ( i = 0; i < maximumNumberOfPeers; i++ )
  2076. {
  2077. if (remoteSystemList[ i ].isActive)
  2078. {
  2079. if ( remoteSystemList[ i ].isActive )
  2080. remoteSystemList[ i ].reliabilityLayer.SetTimeoutTime(timeMS);
  2081. }
  2082. }
  2083. }
  2084. else
  2085. {
  2086. RemoteSystemStruct * remoteSystem = GetRemoteSystemFromSystemAddress( target, false, true );
  2087. if ( remoteSystem != 0 )
  2088. remoteSystem->reliabilityLayer.SetTimeoutTime(timeMS);
  2089. }
  2090. }
  2091. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2092. RakNet::TimeMS RakPeer::GetTimeoutTime( const SystemAddress target )
  2093. {
  2094. if (target==UNASSIGNED_SYSTEM_ADDRESS)
  2095. {
  2096. return defaultTimeoutTime;
  2097. }
  2098. else
  2099. {
  2100. RemoteSystemStruct * remoteSystem = GetRemoteSystemFromSystemAddress( target, false, true );
  2101. if ( remoteSystem != 0 )
  2102. remoteSystem->reliabilityLayer.GetTimeoutTime();
  2103. }
  2104. return defaultTimeoutTime;
  2105. }
  2106. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2107. // Description:
  2108. // Returns the current MTU size
  2109. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2110. int RakPeer::GetMTUSize( const SystemAddress target ) const
  2111. {
  2112. if (target!=UNASSIGNED_SYSTEM_ADDRESS)
  2113. {
  2114. RemoteSystemStruct *rss=GetRemoteSystemFromSystemAddress(target, false, true);
  2115. if (rss)
  2116. return rss->MTUSize;
  2117. }
  2118. return defaultMTUSize;
  2119. }
  2120. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2121. // Description:
  2122. // Returns the number of IP addresses we have
  2123. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2124. unsigned int RakPeer::GetNumberOfAddresses( void )
  2125. {
  2126. if (IsActive()==false)
  2127. {
  2128. FillIPList();
  2129. }
  2130. int i = 0;
  2131. while ( ipList[ i ]!=UNASSIGNED_SYSTEM_ADDRESS )
  2132. i++;
  2133. return i;
  2134. }
  2135. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2136. // Returns an IP address at index 0 to GetNumberOfAddresses-1
  2137. // \param[in] index index into the list of IP addresses
  2138. // \return The local IP address at this index
  2139. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2140. const char* RakPeer::GetLocalIP( unsigned int index )
  2141. {
  2142. if (IsActive()==false)
  2143. {
  2144. // Fill out ipList structure
  2145. FillIPList();
  2146. }
  2147. static char str[128];
  2148. ipList[index].ToString(false,str);
  2149. return str;
  2150. }
  2151. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2152. // Is this a local IP?
  2153. // \param[in] An IP address to check
  2154. // \return True if this is one of the IP addresses returned by GetLocalIP
  2155. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2156. bool RakPeer::IsLocalIP( const char *ip )
  2157. {
  2158. if (ip==0 || ip[0]==0)
  2159. return false;
  2160. if (strcmp(ip, "127.0.0.1")==0 || strcmp(ip, "localhost")==0)
  2161. return true;
  2162. int num = GetNumberOfAddresses();
  2163. int i;
  2164. for (i=0; i < num; i++)
  2165. {
  2166. if (strcmp(ip, GetLocalIP(i))==0)
  2167. return true;
  2168. }
  2169. return false;
  2170. }
  2171. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2172. // Description:
  2173. // Allow or disallow connection responses from any IP. Normally this should be false, but may be necessary
  2174. // when connection to servers with multiple IP addresses
  2175. //
  2176. // Parameters:
  2177. // allow - True to allow this behavior, false to not allow. Defaults to false. Value persists between connections
  2178. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2179. void RakPeer::AllowConnectionResponseIPMigration( bool allow )
  2180. {
  2181. allowConnectionResponseIPMigration = allow;
  2182. }
  2183. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2184. // Description:
  2185. // Sends a message ID_ADVERTISE_SYSTEM to the remote unconnected system.
  2186. // This will tell the remote system our external IP outside the LAN, and can be used for NAT punch through
  2187. //
  2188. // Requires:
  2189. // The sender and recipient must already be started via a successful call to Initialize
  2190. //
  2191. // host: Either a dotted IP address or a domain name
  2192. // remotePort: Which port to connect to on the remote machine.
  2193. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2194. bool RakPeer::AdvertiseSystem( const char *host, unsigned short remotePort, const char *data, int dataLength, unsigned connectionSocketIndex )
  2195. {
  2196. RakNet::BitStream bs;
  2197. bs.Write((MessageID)ID_ADVERTISE_SYSTEM);
  2198. bs.WriteAlignedBytes((const unsigned char*) data,dataLength);
  2199. return SendOutOfBand(host, remotePort, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), connectionSocketIndex );
  2200. }
  2201. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2202. // Controls how often to return ID_DOWNLOAD_PROGRESS for large message downloads.
  2203. // ID_DOWNLOAD_PROGRESS is returned to indicate a new partial message chunk, roughly the MTU size, has arrived
  2204. // As it can be slow or cumbersome to get this notification for every chunk, you can set the interval at which it is returned.
  2205. // Defaults to 0 (never return this notification)
  2206. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2207. void RakPeer::SetSplitMessageProgressInterval(int interval)
  2208. {
  2209. RakAssert(interval>=0);
  2210. splitMessageProgressInterval=interval;
  2211. for ( unsigned short i = 0; i < maximumNumberOfPeers; i++ )
  2212. remoteSystemList[ i ].reliabilityLayer.SetSplitMessageProgressInterval(splitMessageProgressInterval);
  2213. }
  2214. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2215. // Returns what was passed to SetSplitMessageProgressInterval()
  2216. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2217. int RakPeer::GetSplitMessageProgressInterval(void) const
  2218. {
  2219. return splitMessageProgressInterval;
  2220. }
  2221. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2222. // Set how long to wait before giving up on sending an unreliable message
  2223. // Useful if the network is clogged up.
  2224. // Set to 0 or less to never timeout. Defaults to 0.
  2225. // timeoutMS How many ms to wait before simply not sending an unreliable message.
  2226. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2227. void RakPeer::SetUnreliableTimeout(RakNet::TimeMS timeoutMS)
  2228. {
  2229. unreliableTimeout=timeoutMS;
  2230. for ( unsigned short i = 0; i < maximumNumberOfPeers; i++ )
  2231. remoteSystemList[ i ].reliabilityLayer.SetUnreliableTimeout(unreliableTimeout);
  2232. }
  2233. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2234. // Send a message to host, with the IP socket option TTL set to 3
  2235. // This message will not reach the host, but will open the router.
  2236. // Used for NAT-Punchthrough
  2237. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2238. void RakPeer::SendTTL( const char* host, unsigned short remotePort, int ttl, unsigned connectionSocketIndex )
  2239. {
  2240. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  2241. char fakeData[2];
  2242. fakeData[0]=0;
  2243. fakeData[1]=1;
  2244. unsigned int realIndex = GetRakNetSocketFromUserConnectionSocketIndex(connectionSocketIndex);
  2245. if (socketList[realIndex]->IsBerkleySocket())
  2246. {
  2247. RNS2_SendParameters bsp;
  2248. bsp.data = (char*) fakeData;
  2249. bsp.length = 2;
  2250. bsp.systemAddress.FromStringExplicitPort(host,remotePort, socketList[realIndex]->GetBoundAddress().GetIPVersion());
  2251. bsp.systemAddress.FixForIPVersion(socketList[realIndex]->GetBoundAddress());
  2252. bsp.ttl=ttl;
  2253. unsigned i;
  2254. for (i=0; i < pluginListNTS.Size(); i++)
  2255. pluginListNTS[i]->OnDirectSocketSend((const char*)bsp.data, BYTES_TO_BITS(bsp.length), bsp.systemAddress);
  2256. socketList[realIndex]->Send(&bsp, _FILE_AND_LINE_);
  2257. }
  2258. #endif
  2259. }
  2260. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2261. // Attatches a Plugin interface to run code automatically on message receipt in the Receive call
  2262. //
  2263. // \param messageHandler Pointer to a plugin to attach
  2264. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2265. void RakPeer::AttachPlugin( PluginInterface2 *plugin )
  2266. {
  2267. bool isNotThreadsafe = plugin->UsesReliabilityLayer();
  2268. if (isNotThreadsafe)
  2269. {
  2270. if (pluginListNTS.GetIndexOf(plugin)==MAX_UNSIGNED_LONG)
  2271. {
  2272. plugin->SetRakPeerInterface(this);
  2273. plugin->OnAttach();
  2274. pluginListNTS.Insert(plugin, _FILE_AND_LINE_);
  2275. }
  2276. }
  2277. else
  2278. {
  2279. if (pluginListTS.GetIndexOf(plugin)==MAX_UNSIGNED_LONG)
  2280. {
  2281. plugin->SetRakPeerInterface(this);
  2282. plugin->OnAttach();
  2283. pluginListTS.Insert(plugin, _FILE_AND_LINE_);
  2284. }
  2285. }
  2286. }
  2287. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2288. // Detaches a Plugin interface to run code automatically on message receipt
  2289. //
  2290. // \param messageHandler Pointer to a plugin to detach
  2291. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2292. void RakPeer::DetachPlugin( PluginInterface2 *plugin )
  2293. {
  2294. if (plugin==0)
  2295. return;
  2296. unsigned int index;
  2297. bool isNotThreadsafe = plugin->UsesReliabilityLayer();
  2298. if (isNotThreadsafe)
  2299. {
  2300. index = pluginListNTS.GetIndexOf(plugin);
  2301. if (index!=MAX_UNSIGNED_LONG)
  2302. {
  2303. // Unordered list so delete from end for speed
  2304. pluginListNTS[index]=pluginListNTS[pluginListNTS.Size()-1];
  2305. pluginListNTS.RemoveFromEnd();
  2306. }
  2307. }
  2308. else
  2309. {
  2310. index = pluginListTS.GetIndexOf(plugin);
  2311. if (index!=MAX_UNSIGNED_LONG)
  2312. {
  2313. // Unordered list so delete from end for speed
  2314. pluginListTS[index]=pluginListTS[pluginListTS.Size()-1];
  2315. pluginListTS.RemoveFromEnd();
  2316. }
  2317. }
  2318. plugin->OnDetach();
  2319. plugin->SetRakPeerInterface(0);
  2320. }
  2321. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2322. // Put a packet back at the end of the receive queue in case you don't want to deal with it immediately
  2323. //
  2324. // packet The packet you want to push back.
  2325. // pushAtHead True to push the packet so that the next receive call returns it. False to push it at the end of the queue (obviously pushing it at the end makes the packets out of order)
  2326. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2327. void RakPeer::PushBackPacket( Packet *packet, bool pushAtHead)
  2328. {
  2329. if (packet==0)
  2330. return;
  2331. unsigned i;
  2332. for (i=0; i < pluginListTS.Size(); i++)
  2333. pluginListTS[i]->OnPushBackPacket((const char*) packet->data, packet->bitSize, packet->systemAddress);
  2334. for (i=0; i < pluginListNTS.Size(); i++)
  2335. pluginListNTS[i]->OnPushBackPacket((const char*) packet->data, packet->bitSize, packet->systemAddress);
  2336. packetReturnMutex.Lock();
  2337. if (pushAtHead)
  2338. packetReturnQueue.PushAtHead(packet,0,_FILE_AND_LINE_);
  2339. else
  2340. packetReturnQueue.Push(packet,_FILE_AND_LINE_);
  2341. packetReturnMutex.Unlock();
  2342. }
  2343. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2344. void RakPeer::ChangeSystemAddress(RakNetGUID guid, const SystemAddress &systemAddress)
  2345. {
  2346. BufferedCommandStruct *bcs;
  2347. bcs=bufferedCommands.Allocate( _FILE_AND_LINE_ );
  2348. bcs->data = 0;
  2349. bcs->systemIdentifier.systemAddress=systemAddress;
  2350. bcs->systemIdentifier.rakNetGuid=guid;
  2351. bcs->command=BufferedCommandStruct::BCS_CHANGE_SYSTEM_ADDRESS;
  2352. bufferedCommands.Push(bcs);
  2353. }
  2354. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2355. Packet* RakPeer::AllocatePacket(unsigned dataSize)
  2356. {
  2357. return AllocPacket(dataSize, _FILE_AND_LINE_);
  2358. }
  2359. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2360. RakNetSocket2* RakPeer::GetSocket( const SystemAddress target )
  2361. {
  2362. // Send a query to the thread to get the socket, and return when we got it
  2363. BufferedCommandStruct *bcs;
  2364. bcs=bufferedCommands.Allocate( _FILE_AND_LINE_ );
  2365. bcs->command=BufferedCommandStruct::BCS_GET_SOCKET;
  2366. bcs->systemIdentifier=target;
  2367. bcs->data=0;
  2368. bufferedCommands.Push(bcs);
  2369. // Block up to one second to get the socket, although it should actually take virtually no time
  2370. SocketQueryOutput *sqo;
  2371. RakNet::TimeMS stopWaiting = RakNet::GetTimeMS()+1000;
  2372. DataStructures::List<RakNetSocket2* > output;
  2373. while (RakNet::GetTimeMS() < stopWaiting)
  2374. {
  2375. if (isMainLoopThreadActive==false)
  2376. return 0;
  2377. RakSleep(0);
  2378. sqo = socketQueryOutput.Pop();
  2379. if (sqo)
  2380. {
  2381. output=sqo->sockets;
  2382. sqo->sockets.Clear(false, _FILE_AND_LINE_);
  2383. socketQueryOutput.Deallocate(sqo, _FILE_AND_LINE_);
  2384. if (output.Size())
  2385. return output[0];
  2386. break;
  2387. }
  2388. }
  2389. return 0;
  2390. }
  2391. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2392. void RakPeer::GetSockets( DataStructures::List<RakNetSocket2* > &sockets )
  2393. {
  2394. sockets.Clear(false, _FILE_AND_LINE_);
  2395. // Send a query to the thread to get the socket, and return when we got it
  2396. BufferedCommandStruct *bcs;
  2397. bcs=bufferedCommands.Allocate( _FILE_AND_LINE_ );
  2398. bcs->command=BufferedCommandStruct::BCS_GET_SOCKET;
  2399. bcs->systemIdentifier=UNASSIGNED_SYSTEM_ADDRESS;
  2400. bcs->data=0;
  2401. bufferedCommands.Push(bcs);
  2402. // Block up to one second to get the socket, although it should actually take virtually no time
  2403. SocketQueryOutput *sqo;
  2404. // RakNetSocket2* output;
  2405. while (1)
  2406. {
  2407. if (isMainLoopThreadActive==false)
  2408. return;
  2409. RakSleep(0);
  2410. sqo = socketQueryOutput.Pop();
  2411. if (sqo)
  2412. {
  2413. sockets=sqo->sockets;
  2414. sqo->sockets.Clear(false, _FILE_AND_LINE_);
  2415. socketQueryOutput.Deallocate(sqo, _FILE_AND_LINE_);
  2416. return;
  2417. }
  2418. }
  2419. return;
  2420. }
  2421. void RakPeer::ReleaseSockets( DataStructures::List<RakNetSocket2* > &sockets )
  2422. {
  2423. sockets.Clear(false,_FILE_AND_LINE_);
  2424. }
  2425. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2426. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2427. // Adds simulated ping and packet loss to the outgoing data flow.
  2428. // To simulate bi-directional ping and packet loss, you should call this on both the sender and the recipient, with half the total ping and maxSendBPS value on each.
  2429. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2430. void RakPeer::ApplyNetworkSimulator( float packetloss, unsigned short minExtraPing, unsigned short extraPingVariance)
  2431. {
  2432. #ifdef _DEBUG
  2433. if (remoteSystemList)
  2434. {
  2435. unsigned short i;
  2436. for (i=0; i < maximumNumberOfPeers; i++)
  2437. //for (i=0; i < remoteSystemListSize; i++)
  2438. remoteSystemList[i].reliabilityLayer.ApplyNetworkSimulator(packetloss, minExtraPing, extraPingVariance);
  2439. }
  2440. _packetloss=packetloss;
  2441. _minExtraPing=minExtraPing;
  2442. _extraPingVariance=extraPingVariance;
  2443. #endif
  2444. }
  2445. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2446. void RakPeer::SetPerConnectionOutgoingBandwidthLimit( unsigned maxBitsPerSecond )
  2447. {
  2448. maxOutgoingBPS=maxBitsPerSecond;
  2449. }
  2450. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2451. // Returns if you previously called ApplyNetworkSimulator
  2452. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2453. bool RakPeer::IsNetworkSimulatorActive( void )
  2454. {
  2455. #ifdef _DEBUG
  2456. return _packetloss>0 || _minExtraPing>0 || _extraPingVariance>0;
  2457. #else
  2458. return false;
  2459. #endif
  2460. }
  2461. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2462. void RakPeer::WriteOutOfBandHeader(RakNet::BitStream *bitStream)
  2463. {
  2464. bitStream->Write((MessageID)ID_OUT_OF_BAND_INTERNAL);
  2465. bitStream->Write(myGuid);
  2466. bitStream->WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  2467. }
  2468. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2469. void RakPeer::SetUserUpdateThread(void (*_userUpdateThreadPtr)(RakPeerInterface *, void *), void *_userUpdateThreadData)
  2470. {
  2471. userUpdateThreadPtr=_userUpdateThreadPtr;
  2472. userUpdateThreadData=_userUpdateThreadData;
  2473. }
  2474. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2475. void RakPeer::SetIncomingDatagramEventHandler( bool (*_incomingDatagramEventHandler)(RNS2RecvStruct *) )
  2476. {
  2477. incomingDatagramEventHandler=_incomingDatagramEventHandler;
  2478. }
  2479. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2480. bool RakPeer::SendOutOfBand(const char *host, unsigned short remotePort, const char *data, BitSize_t dataLength, unsigned connectionSocketIndex )
  2481. {
  2482. if ( IsActive() == false )
  2483. return false;
  2484. if (host==0 || host[0]==0)
  2485. return false;
  2486. // If this assert hits then Startup wasn't called or the call failed.
  2487. RakAssert(connectionSocketIndex < socketList.Size());
  2488. // This is a security measure. Don't send data longer than this value
  2489. RakAssert(dataLength <= (MAX_OFFLINE_DATA_LENGTH + sizeof(unsigned char)+sizeof(RakNet::Time)+RakNetGUID::size()+sizeof(OFFLINE_MESSAGE_DATA_ID)));
  2490. if (host==0)
  2491. return false;
  2492. // 34 bytes
  2493. RakNet::BitStream bitStream;
  2494. WriteOutOfBandHeader(&bitStream);
  2495. if (dataLength>0)
  2496. {
  2497. bitStream.Write(data, dataLength);
  2498. }
  2499. unsigned int realIndex = GetRakNetSocketFromUserConnectionSocketIndex(connectionSocketIndex);
  2500. /*
  2501. SystemAddress systemAddress;
  2502. systemAddress.FromStringExplicitPort(host,remotePort, socketList[realIndex]->GetBoundAddress().GetIPVersion());
  2503. systemAddress.FixForIPVersion(socketList[realIndex]->GetBoundAddress());
  2504. unsigned i;
  2505. for (i=0; i < pluginListNTS.Size(); i++)
  2506. pluginListNTS[i]->OnDirectSocketSend((const char*)bitStream.GetData(), bitStream.GetNumberOfBitsUsed(), systemAddress);
  2507. SocketLayer::SendTo( socketList[realIndex], (const char*)bitStream.GetData(), (int) bitStream.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  2508. */
  2509. RNS2_SendParameters bsp;
  2510. bsp.data = (char*) bitStream.GetData();
  2511. bsp.length = bitStream.GetNumberOfBytesUsed();
  2512. bsp.systemAddress.FromStringExplicitPort(host,remotePort, socketList[realIndex]->GetBoundAddress().GetIPVersion());
  2513. bsp.systemAddress.FixForIPVersion(socketList[realIndex]->GetBoundAddress());
  2514. unsigned i;
  2515. for (i=0; i < pluginListNTS.Size(); i++)
  2516. pluginListNTS[i]->OnDirectSocketSend((const char*)bsp.data, BYTES_TO_BITS(bsp.length), bsp.systemAddress);
  2517. socketList[realIndex]->Send(&bsp, _FILE_AND_LINE_);
  2518. return true;
  2519. }
  2520. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2521. RakNetStatistics * RakPeer::GetStatistics( const SystemAddress systemAddress, RakNetStatistics *rns )
  2522. {
  2523. static RakNetStatistics staticStatistics;
  2524. RakNetStatistics *systemStats;
  2525. if (rns==0)
  2526. systemStats=&staticStatistics;
  2527. else
  2528. systemStats=rns;
  2529. if (systemAddress==UNASSIGNED_SYSTEM_ADDRESS)
  2530. {
  2531. bool firstWrite=false;
  2532. // Return a crude sum
  2533. for ( unsigned short i = 0; i < maximumNumberOfPeers; i++ )
  2534. {
  2535. if (remoteSystemList[ i ].isActive)
  2536. {
  2537. RakNetStatistics rnsTemp;
  2538. remoteSystemList[ i ].reliabilityLayer.GetStatistics(&rnsTemp);
  2539. if (firstWrite==false)
  2540. {
  2541. memcpy(systemStats, &rnsTemp, sizeof(RakNetStatistics));
  2542. firstWrite=true;
  2543. }
  2544. else
  2545. (*systemStats)+=rnsTemp;
  2546. }
  2547. }
  2548. return systemStats;
  2549. }
  2550. else
  2551. {
  2552. RemoteSystemStruct * rss;
  2553. rss = GetRemoteSystemFromSystemAddress( systemAddress, false, false );
  2554. if ( rss && endThreads==false )
  2555. {
  2556. rss->reliabilityLayer.GetStatistics(systemStats);
  2557. return systemStats;
  2558. }
  2559. }
  2560. return 0;
  2561. }
  2562. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2563. void RakPeer::GetStatisticsList(DataStructures::List<SystemAddress> &addresses, DataStructures::List<RakNetGUID> &guids, DataStructures::List<RakNetStatistics> &statistics)
  2564. {
  2565. addresses.Clear(false, _FILE_AND_LINE_);
  2566. guids.Clear(false, _FILE_AND_LINE_);
  2567. statistics.Clear(false, _FILE_AND_LINE_);
  2568. if ( remoteSystemList == 0 || endThreads == true )
  2569. return;
  2570. unsigned int i;
  2571. for (i=0; i < activeSystemListSize; i++)
  2572. {
  2573. if ((activeSystemList[i])->isActive &&
  2574. (activeSystemList[i])->connectMode==RakPeer::RemoteSystemStruct::CONNECTED)
  2575. {
  2576. addresses.Push((activeSystemList[i])->systemAddress, _FILE_AND_LINE_ );
  2577. guids.Push((activeSystemList[i])->guid, _FILE_AND_LINE_ );
  2578. RakNetStatistics rns;
  2579. (activeSystemList[i])->reliabilityLayer.GetStatistics(&rns);
  2580. statistics.Push(rns, _FILE_AND_LINE_);
  2581. }
  2582. }
  2583. }
  2584. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2585. bool RakPeer::GetStatistics( const unsigned int index, RakNetStatistics *rns )
  2586. {
  2587. if (index < maximumNumberOfPeers && remoteSystemList[ index ].isActive)
  2588. {
  2589. remoteSystemList[ index ].reliabilityLayer.GetStatistics(rns);
  2590. return true;
  2591. }
  2592. return false;
  2593. }
  2594. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2595. unsigned int RakPeer::GetReceiveBufferSize(void)
  2596. {
  2597. unsigned int size;
  2598. packetReturnMutex.Lock();
  2599. size=packetReturnQueue.Size();
  2600. packetReturnMutex.Unlock();
  2601. return size;
  2602. }
  2603. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2604. int RakPeer::GetIndexFromSystemAddress( const SystemAddress systemAddress, bool calledFromNetworkThread ) const
  2605. {
  2606. unsigned i;
  2607. if ( systemAddress == UNASSIGNED_SYSTEM_ADDRESS )
  2608. return -1;
  2609. if (systemAddress.systemIndex!=(SystemIndex)-1 && systemAddress.systemIndex < maximumNumberOfPeers && remoteSystemList[systemAddress.systemIndex].systemAddress==systemAddress && remoteSystemList[ systemAddress.systemIndex ].isActive)
  2610. return systemAddress.systemIndex;
  2611. if (calledFromNetworkThread)
  2612. {
  2613. return GetRemoteSystemIndex(systemAddress);
  2614. }
  2615. else
  2616. {
  2617. // remoteSystemList in user and network thread
  2618. for ( i = 0; i < maximumNumberOfPeers; i++ )
  2619. if ( remoteSystemList[ i ].isActive && remoteSystemList[ i ].systemAddress == systemAddress )
  2620. return i;
  2621. // If no active results found, try previously active results.
  2622. for ( i = 0; i < maximumNumberOfPeers; i++ )
  2623. if ( remoteSystemList[ i ].systemAddress == systemAddress )
  2624. return i;
  2625. }
  2626. return -1;
  2627. }
  2628. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2629. int RakPeer::GetIndexFromGuid( const RakNetGUID guid )
  2630. {
  2631. unsigned i;
  2632. if ( guid == UNASSIGNED_RAKNET_GUID )
  2633. return -1;
  2634. if (guid.systemIndex!=(SystemIndex)-1 && guid.systemIndex < maximumNumberOfPeers && remoteSystemList[guid.systemIndex].guid==guid && remoteSystemList[ guid.systemIndex ].isActive)
  2635. return guid.systemIndex;
  2636. // remoteSystemList in user and network thread
  2637. for ( i = 0; i < maximumNumberOfPeers; i++ )
  2638. if ( remoteSystemList[ i ].isActive && remoteSystemList[ i ].guid == guid )
  2639. return i;
  2640. // If no active results found, try previously active results.
  2641. for ( i = 0; i < maximumNumberOfPeers; i++ )
  2642. if ( remoteSystemList[ i ].guid == guid )
  2643. return i;
  2644. return -1;
  2645. }
  2646. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2647. #if LIBCAT_SECURITY==1
  2648. bool RakPeer::GenerateConnectionRequestChallenge(RequestedConnectionStruct *rcs,PublicKey *publicKey)
  2649. {
  2650. CAT_AUDIT_PRINTF("AUDIT: In GenerateConnectionRequestChallenge()\n");
  2651. rcs->client_handshake = 0;
  2652. rcs->publicKeyMode = PKM_INSECURE_CONNECTION;
  2653. if (!publicKey) return true;
  2654. switch (publicKey->publicKeyMode)
  2655. {
  2656. default:
  2657. case PKM_INSECURE_CONNECTION:
  2658. break;
  2659. case PKM_ACCEPT_ANY_PUBLIC_KEY:
  2660. CAT_OBJCLR(rcs->remote_public_key);
  2661. rcs->client_handshake = RakNet::OP_NEW<cat::ClientEasyHandshake>(_FILE_AND_LINE_);
  2662. rcs->publicKeyMode = PKM_ACCEPT_ANY_PUBLIC_KEY;
  2663. break;
  2664. case PKM_USE_TWO_WAY_AUTHENTICATION:
  2665. if (publicKey->myPublicKey == 0 || publicKey->myPrivateKey == 0 ||
  2666. publicKey->remoteServerPublicKey == 0)
  2667. {
  2668. return false;
  2669. }
  2670. rcs->client_handshake = RakNet::OP_NEW<cat::ClientEasyHandshake>(_FILE_AND_LINE_);
  2671. memcpy(rcs->remote_public_key, publicKey->remoteServerPublicKey, cat::EasyHandshake::PUBLIC_KEY_BYTES);
  2672. if (!rcs->client_handshake->Initialize(publicKey->remoteServerPublicKey) ||
  2673. !rcs->client_handshake->SetIdentity(publicKey->myPublicKey, publicKey->myPrivateKey) ||
  2674. !rcs->client_handshake->GenerateChallenge(rcs->handshakeChallenge))
  2675. {
  2676. CAT_AUDIT_PRINTF("AUDIT: Failure initializing new client_handshake object with identity for this RequestedConnectionStruct\n");
  2677. RakNet::OP_DELETE(rcs->client_handshake,_FILE_AND_LINE_);
  2678. rcs->client_handshake=0;
  2679. return false;
  2680. }
  2681. CAT_AUDIT_PRINTF("AUDIT: Success initializing new client handshake object with identity for this RequestedConnectionStruct -- pre-generated challenge\n");
  2682. rcs->publicKeyMode = PKM_USE_TWO_WAY_AUTHENTICATION;
  2683. break;
  2684. case PKM_USE_KNOWN_PUBLIC_KEY:
  2685. if (publicKey->remoteServerPublicKey == 0)
  2686. return false;
  2687. rcs->client_handshake = RakNet::OP_NEW<cat::ClientEasyHandshake>(_FILE_AND_LINE_);
  2688. memcpy(rcs->remote_public_key, publicKey->remoteServerPublicKey, cat::EasyHandshake::PUBLIC_KEY_BYTES);
  2689. if (!rcs->client_handshake->Initialize(publicKey->remoteServerPublicKey) ||
  2690. !rcs->client_handshake->GenerateChallenge(rcs->handshakeChallenge))
  2691. {
  2692. CAT_AUDIT_PRINTF("AUDIT: Failure initializing new client_handshake object for this RequestedConnectionStruct\n");
  2693. RakNet::OP_DELETE(rcs->client_handshake,_FILE_AND_LINE_);
  2694. rcs->client_handshake=0;
  2695. return false;
  2696. }
  2697. CAT_AUDIT_PRINTF("AUDIT: Success initializing new client handshake object for this RequestedConnectionStruct -- pre-generated challenge\n");
  2698. rcs->publicKeyMode = PKM_USE_KNOWN_PUBLIC_KEY;
  2699. break;
  2700. }
  2701. return true;
  2702. }
  2703. #endif
  2704. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2705. ConnectionAttemptResult RakPeer::SendConnectionRequest( const char* host, unsigned short remotePort, const char *passwordData, int passwordDataLength, PublicKey *publicKey, unsigned connectionSocketIndex, unsigned int extraData, unsigned sendConnectionAttemptCount, unsigned timeBetweenSendConnectionAttemptsMS, RakNet::TimeMS timeoutTime )
  2706. {
  2707. RakAssert(passwordDataLength <= 256);
  2708. RakAssert(remotePort!=0);
  2709. SystemAddress systemAddress;
  2710. if (!systemAddress.FromStringExplicitPort(host,remotePort,socketList[connectionSocketIndex]->GetBoundAddress().GetIPVersion()))
  2711. return CANNOT_RESOLVE_DOMAIN_NAME;
  2712. // Already connected?
  2713. if (GetRemoteSystemFromSystemAddress(systemAddress, false, true))
  2714. return ALREADY_CONNECTED_TO_ENDPOINT;
  2715. //RequestedConnectionStruct *rcs = (RequestedConnectionStruct *) rakMalloc_Ex(sizeof(RequestedConnectionStruct), _FILE_AND_LINE_);
  2716. RequestedConnectionStruct *rcs = RakNet::OP_NEW<RequestedConnectionStruct>(_FILE_AND_LINE_);
  2717. rcs->systemAddress=systemAddress;
  2718. rcs->nextRequestTime=RakNet::GetTimeMS();
  2719. rcs->requestsMade=0;
  2720. rcs->data=0;
  2721. rcs->socket=0;
  2722. rcs->extraData=extraData;
  2723. rcs->socketIndex=connectionSocketIndex;
  2724. rcs->actionToTake=RequestedConnectionStruct::CONNECT;
  2725. rcs->sendConnectionAttemptCount=sendConnectionAttemptCount;
  2726. rcs->timeBetweenSendConnectionAttemptsMS=timeBetweenSendConnectionAttemptsMS;
  2727. memcpy(rcs->outgoingPassword, passwordData, passwordDataLength);
  2728. rcs->outgoingPasswordLength=(unsigned char) passwordDataLength;
  2729. rcs->timeoutTime=timeoutTime;
  2730. #if LIBCAT_SECURITY==1
  2731. CAT_AUDIT_PRINTF("AUDIT: In SendConnectionRequest()\n");
  2732. if (!GenerateConnectionRequestChallenge(rcs,publicKey))
  2733. return SECURITY_INITIALIZATION_FAILED;
  2734. #else
  2735. (void) publicKey;
  2736. #endif
  2737. // Return false if already pending, else push on queue
  2738. unsigned int i=0;
  2739. requestedConnectionQueueMutex.Lock();
  2740. for (; i < requestedConnectionQueue.Size(); i++)
  2741. {
  2742. if (requestedConnectionQueue[i]->systemAddress==systemAddress)
  2743. {
  2744. requestedConnectionQueueMutex.Unlock();
  2745. // Not necessary
  2746. //RakNet::OP_DELETE(rcs->client_handshake,_FILE_AND_LINE_);
  2747. RakNet::OP_DELETE(rcs,_FILE_AND_LINE_);
  2748. return CONNECTION_ATTEMPT_ALREADY_IN_PROGRESS;
  2749. }
  2750. }
  2751. requestedConnectionQueue.Push(rcs, _FILE_AND_LINE_ );
  2752. requestedConnectionQueueMutex.Unlock();
  2753. return CONNECTION_ATTEMPT_STARTED;
  2754. }
  2755. ConnectionAttemptResult RakPeer::SendConnectionRequest( const char* host, unsigned short remotePort, const char *passwordData, int passwordDataLength, PublicKey *publicKey, unsigned connectionSocketIndex, unsigned int extraData, unsigned sendConnectionAttemptCount, unsigned timeBetweenSendConnectionAttemptsMS, RakNet::TimeMS timeoutTime, RakNetSocket2* socket )
  2756. {
  2757. RakAssert(passwordDataLength <= 256);
  2758. SystemAddress systemAddress;
  2759. systemAddress.FromStringExplicitPort(host,remotePort);
  2760. // Already connected?
  2761. if (GetRemoteSystemFromSystemAddress(systemAddress, false, true))
  2762. return ALREADY_CONNECTED_TO_ENDPOINT;
  2763. //RequestedConnectionStruct *rcs = (RequestedConnectionStruct *) rakMalloc_Ex(sizeof(RequestedConnectionStruct), _FILE_AND_LINE_);
  2764. RequestedConnectionStruct *rcs = RakNet::OP_NEW<RequestedConnectionStruct>(_FILE_AND_LINE_);
  2765. rcs->systemAddress=systemAddress;
  2766. rcs->nextRequestTime=RakNet::GetTimeMS();
  2767. rcs->requestsMade=0;
  2768. rcs->data=0;
  2769. rcs->socket=0;
  2770. rcs->extraData=extraData;
  2771. rcs->socketIndex=connectionSocketIndex;
  2772. rcs->actionToTake=RequestedConnectionStruct::CONNECT;
  2773. rcs->sendConnectionAttemptCount=sendConnectionAttemptCount;
  2774. rcs->timeBetweenSendConnectionAttemptsMS=timeBetweenSendConnectionAttemptsMS;
  2775. memcpy(rcs->outgoingPassword, passwordData, passwordDataLength);
  2776. rcs->outgoingPasswordLength=(unsigned char) passwordDataLength;
  2777. rcs->timeoutTime=timeoutTime;
  2778. rcs->socket=socket;
  2779. #if LIBCAT_SECURITY==1
  2780. if (!GenerateConnectionRequestChallenge(rcs,publicKey))
  2781. return SECURITY_INITIALIZATION_FAILED;
  2782. #else
  2783. (void) publicKey;
  2784. #endif
  2785. // Return false if already pending, else push on queue
  2786. unsigned int i=0;
  2787. requestedConnectionQueueMutex.Lock();
  2788. for (; i < requestedConnectionQueue.Size(); i++)
  2789. {
  2790. if (requestedConnectionQueue[i]->systemAddress==systemAddress)
  2791. {
  2792. requestedConnectionQueueMutex.Unlock();
  2793. // Not necessary
  2794. //RakNet::OP_DELETE(rcs->client_handshake,_FILE_AND_LINE_);
  2795. RakNet::OP_DELETE(rcs,_FILE_AND_LINE_);
  2796. return CONNECTION_ATTEMPT_ALREADY_IN_PROGRESS;
  2797. }
  2798. }
  2799. requestedConnectionQueue.Push(rcs, _FILE_AND_LINE_ );
  2800. requestedConnectionQueueMutex.Unlock();
  2801. return CONNECTION_ATTEMPT_STARTED;
  2802. }
  2803. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2804. void RakPeer::ValidateRemoteSystemLookup(void) const
  2805. {
  2806. }
  2807. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2808. RakPeer::RemoteSystemStruct *RakPeer::GetRemoteSystem( const AddressOrGUID systemIdentifier, bool calledFromNetworkThread, bool onlyActive ) const
  2809. {
  2810. if (systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID)
  2811. return GetRemoteSystemFromGUID(systemIdentifier.rakNetGuid, onlyActive);
  2812. else
  2813. return GetRemoteSystemFromSystemAddress(systemIdentifier.systemAddress, calledFromNetworkThread, onlyActive);
  2814. }
  2815. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2816. RakPeer::RemoteSystemStruct *RakPeer::GetRemoteSystemFromSystemAddress( const SystemAddress systemAddress, bool calledFromNetworkThread, bool onlyActive ) const
  2817. {
  2818. unsigned i;
  2819. if ( systemAddress == UNASSIGNED_SYSTEM_ADDRESS )
  2820. return 0;
  2821. if (calledFromNetworkThread)
  2822. {
  2823. unsigned int index = GetRemoteSystemIndex(systemAddress);
  2824. if (index!=(unsigned int) -1)
  2825. {
  2826. if (onlyActive==false || remoteSystemList[ index ].isActive==true )
  2827. {
  2828. RakAssert(remoteSystemList[index].systemAddress==systemAddress);
  2829. return remoteSystemList + index;
  2830. }
  2831. }
  2832. }
  2833. else
  2834. {
  2835. int deadConnectionIndex=-1;
  2836. // Active connections take priority. But if there are no active connections, return the first systemAddress match found
  2837. for ( i = 0; i < maximumNumberOfPeers; i++ )
  2838. {
  2839. if (remoteSystemList[ i ].systemAddress == systemAddress)
  2840. {
  2841. if ( remoteSystemList[ i ].isActive )
  2842. return remoteSystemList + i;
  2843. else if (deadConnectionIndex==-1)
  2844. deadConnectionIndex=i;
  2845. }
  2846. }
  2847. if (deadConnectionIndex!=-1 && onlyActive==false)
  2848. return remoteSystemList + deadConnectionIndex;
  2849. }
  2850. return 0;
  2851. }
  2852. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2853. RakPeer::RemoteSystemStruct *RakPeer::GetRemoteSystemFromGUID( const RakNetGUID guid, bool onlyActive ) const
  2854. {
  2855. if (guid==UNASSIGNED_RAKNET_GUID)
  2856. return 0;
  2857. unsigned i;
  2858. for ( i = 0; i < maximumNumberOfPeers; i++ )
  2859. {
  2860. if (remoteSystemList[ i ].guid == guid && (onlyActive==false || remoteSystemList[ i ].isActive))
  2861. {
  2862. return remoteSystemList + i;
  2863. }
  2864. }
  2865. return 0;
  2866. }
  2867. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2868. void RakPeer::ParseConnectionRequestPacket( RakPeer::RemoteSystemStruct *remoteSystem, const SystemAddress &systemAddress, const char *data, int byteSize )
  2869. {
  2870. RakNet::BitStream bs((unsigned char*) data,byteSize,false);
  2871. bs.IgnoreBytes(sizeof(MessageID));
  2872. RakNetGUID guid;
  2873. bs.Read(guid);
  2874. RakNet::Time incomingTimestamp;
  2875. bs.Read(incomingTimestamp);
  2876. unsigned char doSecurity;
  2877. bs.Read(doSecurity);
  2878. #if LIBCAT_SECURITY==1
  2879. unsigned char doClientKey;
  2880. if (_using_security)
  2881. {
  2882. // Ignore message on bad state
  2883. if (doSecurity != 1 || !remoteSystem->reliabilityLayer.GetAuthenticatedEncryption())
  2884. return;
  2885. // Validate client proof of key
  2886. unsigned char proof[cat::EasyHandshake::PROOF_BYTES];
  2887. bs.ReadAlignedBytes(proof, sizeof(proof));
  2888. if (!remoteSystem->reliabilityLayer.GetAuthenticatedEncryption()->ValidateProof(proof, sizeof(proof)))
  2889. {
  2890. remoteSystem->connectMode = RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY;
  2891. return;
  2892. }
  2893. CAT_OBJCLR(remoteSystem->client_public_key);
  2894. bs.Read(doClientKey);
  2895. // Check if client wants to prove identity
  2896. if (doClientKey == 1)
  2897. {
  2898. // Read identity proof
  2899. unsigned char ident[cat::EasyHandshake::IDENTITY_BYTES];
  2900. bs.ReadAlignedBytes(ident, sizeof(ident));
  2901. // If we are listening to these proofs,
  2902. if (_require_client_public_key)
  2903. {
  2904. // Validate client identity
  2905. if (!_server_handshake->VerifyInitiatorIdentity(remoteSystem->answer, ident, remoteSystem->client_public_key))
  2906. {
  2907. RakNet::BitStream bitStream;
  2908. bitStream.Write((MessageID)ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY); // Report an error since the client is not providing an identity when it is necessary to connect
  2909. bitStream.Write((unsigned char)2); // Indicate client identity is invalid
  2910. SendImmediate((char*) bitStream.GetData(), bitStream.GetNumberOfBytesUsed(), IMMEDIATE_PRIORITY, RELIABLE, 0, systemAddress, false, false, RakNet::GetTimeUS(), 0);
  2911. remoteSystem->connectMode = RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY;
  2912. return;
  2913. }
  2914. }
  2915. // Otherwise ignore the client public key
  2916. }
  2917. else
  2918. {
  2919. // If no client key was provided but it is required,
  2920. if (_require_client_public_key)
  2921. {
  2922. RakNet::BitStream bitStream;
  2923. bitStream.Write((MessageID)ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY); // Report an error since the client is not providing an identity when it is necessary to connect
  2924. bitStream.Write((unsigned char)1); // Indicate client identity is missing
  2925. SendImmediate((char*) bitStream.GetData(), bitStream.GetNumberOfBytesUsed(), IMMEDIATE_PRIORITY, RELIABLE, 0, systemAddress, false, false, RakNet::GetTimeUS(), 0);
  2926. remoteSystem->connectMode = RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY;
  2927. return;
  2928. }
  2929. }
  2930. }
  2931. #endif // LIBCAT_SECURITY
  2932. unsigned char *password = bs.GetData()+BITS_TO_BYTES(bs.GetReadOffset());
  2933. int passwordLength = byteSize - BITS_TO_BYTES(bs.GetReadOffset());
  2934. if ( incomingPasswordLength != passwordLength ||
  2935. memcmp( password, incomingPassword, incomingPasswordLength ) != 0 )
  2936. {
  2937. CAT_AUDIT_PRINTF("AUDIT: Invalid password\n");
  2938. // This one we only send once since we don't care if it arrives.
  2939. RakNet::BitStream bitStream;
  2940. bitStream.Write((MessageID)ID_INVALID_PASSWORD);
  2941. bitStream.Write(GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
  2942. SendImmediate((char*) bitStream.GetData(), bitStream.GetNumberOfBytesUsed(), IMMEDIATE_PRIORITY, RELIABLE, 0, systemAddress, false, false, RakNet::GetTimeUS(), 0);
  2943. remoteSystem->connectMode=RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY;
  2944. return;
  2945. }
  2946. // OK
  2947. remoteSystem->connectMode=RemoteSystemStruct::HANDLING_CONNECTION_REQUEST;
  2948. OnConnectionRequest( remoteSystem, incomingTimestamp );
  2949. }
  2950. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2951. void RakPeer::OnConnectionRequest( RakPeer::RemoteSystemStruct *remoteSystem, RakNet::Time incomingTimestamp )
  2952. {
  2953. RakNet::BitStream bitStream;
  2954. bitStream.Write((MessageID)ID_CONNECTION_REQUEST_ACCEPTED);
  2955. bitStream.Write(remoteSystem->systemAddress);
  2956. SystemIndex systemIndex = (SystemIndex) GetIndexFromSystemAddress( remoteSystem->systemAddress, true );
  2957. RakAssert(systemIndex!=65535);
  2958. bitStream.Write(systemIndex);
  2959. for (unsigned int i=0; i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++)
  2960. bitStream.Write(ipList[i]);
  2961. bitStream.Write(incomingTimestamp);
  2962. bitStream.Write(RakNet::GetTime());
  2963. SendImmediate((char*)bitStream.GetData(), bitStream.GetNumberOfBitsUsed(), IMMEDIATE_PRIORITY, RELIABLE_ORDERED, 0, remoteSystem->systemAddress, false, false, RakNet::GetTimeUS(), 0);
  2964. }
  2965. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2966. void RakPeer::NotifyAndFlagForShutdown( const SystemAddress systemAddress, bool performImmediate, unsigned char orderingChannel, PacketPriority disconnectionNotificationPriority )
  2967. {
  2968. RakNet::BitStream temp( sizeof(unsigned char) );
  2969. temp.Write( (MessageID)ID_DISCONNECTION_NOTIFICATION );
  2970. if (performImmediate)
  2971. {
  2972. SendImmediate((char*)temp.GetData(), temp.GetNumberOfBitsUsed(), disconnectionNotificationPriority, RELIABLE_ORDERED, orderingChannel, systemAddress, false, false, RakNet::GetTimeUS(), 0);
  2973. RemoteSystemStruct *rss=GetRemoteSystemFromSystemAddress(systemAddress, true, true);
  2974. rss->connectMode=RemoteSystemStruct::DISCONNECT_ASAP;
  2975. }
  2976. else
  2977. {
  2978. SendBuffered((const char*)temp.GetData(), temp.GetNumberOfBitsUsed(), disconnectionNotificationPriority, RELIABLE_ORDERED, orderingChannel, systemAddress, false, RemoteSystemStruct::DISCONNECT_ASAP, 0);
  2979. }
  2980. }
  2981. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  2982. unsigned int RakPeer::GetNumberOfRemoteInitiatedConnections( void ) const
  2983. {
  2984. if ( remoteSystemList == 0 || endThreads == true )
  2985. return 0;
  2986. unsigned int numberOfIncomingConnections;
  2987. numberOfIncomingConnections = 0;
  2988. unsigned int i;
  2989. for (i=0; i < activeSystemListSize; i++)
  2990. {
  2991. if ((activeSystemList[i])->isActive &&
  2992. (activeSystemList[i])->connectMode==RakPeer::RemoteSystemStruct::CONNECTED &&
  2993. (activeSystemList[i])->weInitiatedTheConnection==false
  2994. )
  2995. {
  2996. numberOfIncomingConnections++;
  2997. }
  2998. }
  2999. return numberOfIncomingConnections;
  3000. }
  3001. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3002. RakPeer::RemoteSystemStruct * RakPeer::AssignSystemAddressToRemoteSystemList( const SystemAddress systemAddress, RemoteSystemStruct::ConnectMode connectionMode, RakNetSocket2* incomingRakNetSocket, bool *thisIPConnectedRecently, SystemAddress bindingAddress, int incomingMTU, RakNetGUID guid, bool useSecurity )
  3003. {
  3004. RemoteSystemStruct * remoteSystem;
  3005. unsigned i,j,assignedIndex;
  3006. RakNet::TimeMS time = RakNet::GetTimeMS();
  3007. #ifdef _DEBUG
  3008. RakAssert(systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
  3009. #endif
  3010. if (limitConnectionFrequencyFromTheSameIP)
  3011. {
  3012. if (IsLoopbackAddress(systemAddress,false)==false)
  3013. {
  3014. for ( i = 0; i < maximumNumberOfPeers; i++ )
  3015. {
  3016. if ( remoteSystemList[ i ].isActive==true &&
  3017. remoteSystemList[ i ].systemAddress.EqualsExcludingPort(systemAddress) &&
  3018. time >= remoteSystemList[ i ].connectionTime &&
  3019. time - remoteSystemList[ i ].connectionTime < 100
  3020. )
  3021. {
  3022. // 4/13/09 Attackers can flood ID_OPEN_CONNECTION_REQUEST and use up all available connection slots
  3023. // Ignore connection attempts if this IP address connected within the last 100 milliseconds
  3024. *thisIPConnectedRecently=true;
  3025. ValidateRemoteSystemLookup();
  3026. return 0;
  3027. }
  3028. }
  3029. }
  3030. }
  3031. // Don't use a different port than what we received on
  3032. bindingAddress.CopyPort(incomingRakNetSocket->GetBoundAddress());
  3033. *thisIPConnectedRecently=false;
  3034. for ( assignedIndex = 0; assignedIndex < maximumNumberOfPeers; assignedIndex++ )
  3035. {
  3036. if ( remoteSystemList[ assignedIndex ].isActive==false )
  3037. {
  3038. // printf("--- Address %s has become active\n", systemAddress.ToString());
  3039. remoteSystem=remoteSystemList+assignedIndex;
  3040. ReferenceRemoteSystem(systemAddress, assignedIndex);
  3041. remoteSystem->MTUSize=defaultMTUSize;
  3042. remoteSystem->guid=guid;
  3043. remoteSystem->isActive = true; // This one line causes future incoming packets to go through the reliability layer
  3044. // Reserve this reliability layer for ourselves.
  3045. if (incomingMTU > remoteSystem->MTUSize)
  3046. remoteSystem->MTUSize=incomingMTU;
  3047. RakAssert(remoteSystem->MTUSize <= MAXIMUM_MTU_SIZE);
  3048. remoteSystem->reliabilityLayer.Reset(true, remoteSystem->MTUSize, useSecurity);
  3049. remoteSystem->reliabilityLayer.SetSplitMessageProgressInterval(splitMessageProgressInterval);
  3050. remoteSystem->reliabilityLayer.SetUnreliableTimeout(unreliableTimeout);
  3051. remoteSystem->reliabilityLayer.SetTimeoutTime(defaultTimeoutTime);
  3052. AddToActiveSystemList(assignedIndex);
  3053. if (incomingRakNetSocket->GetBoundAddress()==bindingAddress)
  3054. {
  3055. remoteSystem->rakNetSocket=incomingRakNetSocket;
  3056. }
  3057. else
  3058. {
  3059. char str[256];
  3060. bindingAddress.ToString(true,str);
  3061. // See if this is an internal IP address.
  3062. // If so, force binding on it so we reply on the same IP address as they sent to.
  3063. unsigned int ipListIndex, foundIndex=(unsigned int)-1;
  3064. for (ipListIndex=0; ipListIndex < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ipListIndex++)
  3065. {
  3066. if (ipList[ipListIndex]==UNASSIGNED_SYSTEM_ADDRESS)
  3067. break;
  3068. if (bindingAddress.EqualsExcludingPort(ipList[ipListIndex]))
  3069. {
  3070. foundIndex=ipListIndex;
  3071. break;
  3072. }
  3073. }
  3074. // 06/26/09 Unconfirmed report that Vista firewall blocks the reply if we force a binding
  3075. // For now use the incoming socket only
  3076. // Originally this code was to force a machine with multiple IP addresses to reply back on the IP
  3077. // that the datagram came in on
  3078. if (1 || foundIndex==(unsigned int)-1)
  3079. {
  3080. // Must not be an internal LAN address. Just use whatever socket it came in on
  3081. remoteSystem->rakNetSocket=incomingRakNetSocket;
  3082. }
  3083. else
  3084. {
  3085. /*
  3086. // Force binding
  3087. unsigned int socketListIndex;
  3088. for (socketListIndex=0; socketListIndex < socketList.Size(); socketListIndex++)
  3089. {
  3090. if (socketList[socketListIndex]->GetBoundAddress()==bindingAddress)
  3091. {
  3092. // Force binding with existing socket
  3093. remoteSystem->rakNetSocket=socketList[socketListIndex];
  3094. break;
  3095. }
  3096. }
  3097. if (socketListIndex==socketList.Size())
  3098. {
  3099. char ipListFoundIndexStr[128];
  3100. ipList[foundIndex].ToString(false,str);
  3101. // Force binding with new socket
  3102. RakNetSocket* rns(RakNet::OP_NEW<RakNetSocket>(_FILE_AND_LINE_));
  3103. if (incomingRakNetSocket->GetRemotePortRakNetWasStartedOn()==0)
  3104. rns = SocketLayer::CreateBoundSocket( this, bindingAddress.GetPort(), incomingRakNetSocket->GetBlockingSocket(), ipListFoundIndexStr, 0, incomingRakNetSocket->GetExtraSocketOptions(), incomingRakNetSocket->GetSocketFamily(), incomingRakNetSocket->GetChromeInstance() );
  3105. else
  3106. rns = SocketLayer::CreateBoundSocket_PS3Lobby( bindingAddress.GetPort(), incomingRakNetSocket->GetBlockingSocket(), ipListFoundIndexStr, incomingRakNetSocket->GetSocketFamily() );
  3107. if (rns==0)
  3108. {
  3109. // Can't bind. Just use whatever socket it came in on
  3110. remoteSystem->rakNetSocket=incomingRakNetSocket;
  3111. }
  3112. else
  3113. {
  3114. rns->GetBoundAddress()=bindingAddress;
  3115. rns->SetUserConnectionSocketIndex((unsigned int)-1);
  3116. socketList.Push(rns, _FILE_AND_LINE_ );
  3117. remoteSystem->rakNetSocket=rns;
  3118. #ifdef _WIN32
  3119. int highPriority=THREAD_PRIORITY_ABOVE_NORMAL;
  3120. #else
  3121. int highPriority=-10;
  3122. #endif
  3123. highPriority=0;
  3124. }
  3125. }
  3126. */
  3127. }
  3128. }
  3129. for ( j = 0; j < (unsigned) PING_TIMES_ARRAY_SIZE; j++ )
  3130. {
  3131. remoteSystem->pingAndClockDifferential[ j ].pingTime = 65535;
  3132. remoteSystem->pingAndClockDifferential[ j ].clockDifferential = 0;
  3133. }
  3134. remoteSystem->connectMode=connectionMode;
  3135. remoteSystem->pingAndClockDifferentialWriteIndex = 0;
  3136. remoteSystem->lowestPing = 65535;
  3137. remoteSystem->nextPingTime = 0; // Ping immediately
  3138. remoteSystem->weInitiatedTheConnection = false;
  3139. remoteSystem->connectionTime = time;
  3140. remoteSystem->myExternalSystemAddress = UNASSIGNED_SYSTEM_ADDRESS;
  3141. remoteSystem->lastReliableSend=time;
  3142. #ifdef _DEBUG
  3143. int indexLoopupCheck=GetIndexFromSystemAddress( systemAddress, true );
  3144. if ((int) indexLoopupCheck!=(int) assignedIndex)
  3145. {
  3146. RakAssert((int) indexLoopupCheck==(int) assignedIndex);
  3147. }
  3148. #endif
  3149. return remoteSystem;
  3150. }
  3151. }
  3152. return 0;
  3153. }
  3154. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3155. // Adjust the first four bytes (treated as unsigned int) of the pointer
  3156. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3157. void RakPeer::ShiftIncomingTimestamp( unsigned char *data, const SystemAddress &systemAddress ) const
  3158. {
  3159. #ifdef _DEBUG
  3160. RakAssert( IsActive() );
  3161. RakAssert( data );
  3162. #endif
  3163. RakNet::BitStream timeBS( data, sizeof(RakNet::Time), false);
  3164. RakNet::Time encodedTimestamp;
  3165. timeBS.Read(encodedTimestamp);
  3166. encodedTimestamp = encodedTimestamp - GetBestClockDifferential( systemAddress );
  3167. timeBS.SetWriteOffset(0);
  3168. timeBS.Write(encodedTimestamp);
  3169. }
  3170. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3171. // Thanks to Chris Taylor (cat02e@fsu.edu) for the improved timestamping algorithm
  3172. RakNet::Time RakPeer::GetBestClockDifferential( const SystemAddress systemAddress ) const
  3173. {
  3174. RemoteSystemStruct *remoteSystem = GetRemoteSystemFromSystemAddress( systemAddress, true, true );
  3175. if ( remoteSystem == 0 )
  3176. return 0;
  3177. return GetClockDifferentialInt(remoteSystem);
  3178. }
  3179. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3180. unsigned int RakPeer::RemoteSystemLookupHashIndex(const SystemAddress &sa) const
  3181. {
  3182. return SystemAddress::ToInteger(sa) % ((unsigned int) maximumNumberOfPeers * REMOTE_SYSTEM_LOOKUP_HASH_MULTIPLE);
  3183. }
  3184. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3185. void RakPeer::ReferenceRemoteSystem(const SystemAddress &sa, unsigned int remoteSystemListIndex)
  3186. {
  3187. // #ifdef _DEBUG
  3188. // for ( int remoteSystemIndex = 0; remoteSystemIndex < maximumNumberOfPeers; ++remoteSystemIndex )
  3189. // {
  3190. // if (remoteSystemList[remoteSystemIndex].isActive )
  3191. // {
  3192. // unsigned int hashIndex = GetRemoteSystemIndex(remoteSystemList[remoteSystemIndex].systemAddress);
  3193. // RakAssert(hashIndex==remoteSystemIndex);
  3194. // }
  3195. // }
  3196. // #endif
  3197. SystemAddress oldAddress = remoteSystemList[remoteSystemListIndex].systemAddress;
  3198. if (oldAddress!=UNASSIGNED_SYSTEM_ADDRESS)
  3199. {
  3200. // The system might be active if rerouting
  3201. // RakAssert(remoteSystemList[remoteSystemListIndex].isActive==false);
  3202. // Remove the reference if the reference is pointing to this inactive system
  3203. if (GetRemoteSystem(oldAddress)==&remoteSystemList[remoteSystemListIndex])
  3204. DereferenceRemoteSystem(oldAddress);
  3205. }
  3206. DereferenceRemoteSystem(sa);
  3207. // #ifdef _DEBUG
  3208. // for ( int remoteSystemIndex = 0; remoteSystemIndex < maximumNumberOfPeers; ++remoteSystemIndex )
  3209. // {
  3210. // if (remoteSystemList[remoteSystemIndex].isActive )
  3211. // {
  3212. // unsigned int hashIndex = GetRemoteSystemIndex(remoteSystemList[remoteSystemIndex].systemAddress);
  3213. // if (hashIndex!=remoteSystemIndex)
  3214. // {
  3215. // RakAssert(hashIndex==remoteSystemIndex);
  3216. // }
  3217. // }
  3218. // }
  3219. // #endif
  3220. remoteSystemList[remoteSystemListIndex].systemAddress=sa;
  3221. unsigned int hashIndex = RemoteSystemLookupHashIndex(sa);
  3222. RemoteSystemIndex *rsi;
  3223. rsi = remoteSystemIndexPool.Allocate(_FILE_AND_LINE_);
  3224. if (remoteSystemLookup[hashIndex]==0)
  3225. {
  3226. rsi->next=0;
  3227. rsi->index=remoteSystemListIndex;
  3228. remoteSystemLookup[hashIndex]=rsi;
  3229. }
  3230. else
  3231. {
  3232. RemoteSystemIndex *cur = remoteSystemLookup[hashIndex];
  3233. while (cur->next!=0)
  3234. {
  3235. cur=cur->next;
  3236. }
  3237. rsi = remoteSystemIndexPool.Allocate(_FILE_AND_LINE_);
  3238. rsi->next=0;
  3239. rsi->index=remoteSystemListIndex;
  3240. cur->next=rsi;
  3241. }
  3242. // #ifdef _DEBUG
  3243. // for ( int remoteSystemIndex = 0; remoteSystemIndex < maximumNumberOfPeers; ++remoteSystemIndex )
  3244. // {
  3245. // if (remoteSystemList[remoteSystemIndex].isActive )
  3246. // {
  3247. // unsigned int hashIndex = GetRemoteSystemIndex(remoteSystemList[remoteSystemIndex].systemAddress);
  3248. // RakAssert(hashIndex==remoteSystemIndex);
  3249. // }
  3250. // }
  3251. // #endif
  3252. RakAssert(GetRemoteSystemIndex(sa)==remoteSystemListIndex);
  3253. }
  3254. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3255. void RakPeer::DereferenceRemoteSystem(const SystemAddress &sa)
  3256. {
  3257. unsigned int hashIndex = RemoteSystemLookupHashIndex(sa);
  3258. RemoteSystemIndex *cur = remoteSystemLookup[hashIndex];
  3259. RemoteSystemIndex *last = 0;
  3260. while (cur!=0)
  3261. {
  3262. if (remoteSystemList[cur->index].systemAddress==sa)
  3263. {
  3264. if (last==0)
  3265. {
  3266. remoteSystemLookup[hashIndex]=cur->next;
  3267. }
  3268. else
  3269. {
  3270. last->next=cur->next;
  3271. }
  3272. remoteSystemIndexPool.Release(cur,_FILE_AND_LINE_);
  3273. break;
  3274. }
  3275. last=cur;
  3276. cur=cur->next;
  3277. }
  3278. }
  3279. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3280. unsigned int RakPeer::GetRemoteSystemIndex(const SystemAddress &sa) const
  3281. {
  3282. unsigned int hashIndex = RemoteSystemLookupHashIndex(sa);
  3283. RemoteSystemIndex *cur = remoteSystemLookup[hashIndex];
  3284. while (cur!=0)
  3285. {
  3286. if (remoteSystemList[cur->index].systemAddress==sa)
  3287. return cur->index;
  3288. cur=cur->next;
  3289. }
  3290. return (unsigned int) -1;
  3291. }
  3292. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3293. RakPeer::RemoteSystemStruct* RakPeer::GetRemoteSystem(const SystemAddress &sa) const
  3294. {
  3295. unsigned int remoteSystemIndex = GetRemoteSystemIndex(sa);
  3296. if (remoteSystemIndex==(unsigned int)-1)
  3297. return 0;
  3298. return remoteSystemList + remoteSystemIndex;
  3299. }
  3300. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3301. void RakPeer::ClearRemoteSystemLookup(void)
  3302. {
  3303. remoteSystemIndexPool.Clear(_FILE_AND_LINE_);
  3304. RakNet::OP_DELETE_ARRAY(remoteSystemLookup,_FILE_AND_LINE_);
  3305. remoteSystemLookup=0;
  3306. }
  3307. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3308. void RakPeer::AddToActiveSystemList(unsigned int remoteSystemListIndex)
  3309. {
  3310. activeSystemList[activeSystemListSize++]=remoteSystemList+remoteSystemListIndex;
  3311. }
  3312. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3313. void RakPeer::RemoveFromActiveSystemList(const SystemAddress &sa)
  3314. {
  3315. unsigned int i;
  3316. for (i=0; i < activeSystemListSize; i++)
  3317. {
  3318. RemoteSystemStruct *rss=activeSystemList[i];
  3319. if (rss->systemAddress==sa)
  3320. {
  3321. activeSystemList[i]=activeSystemList[activeSystemListSize-1];
  3322. activeSystemListSize--;
  3323. return;
  3324. }
  3325. }
  3326. RakAssert("activeSystemList invalid, entry not found in RemoveFromActiveSystemList. Ensure that AddToActiveSystemList and RemoveFromActiveSystemList are called by the same thread." && 0);
  3327. }
  3328. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3329. /*
  3330. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3331. unsigned int RakPeer::LookupIndexUsingHashIndex(const SystemAddress &sa) const
  3332. {
  3333. unsigned int scanCount=0;
  3334. unsigned int index = RemoteSystemLookupHashIndex(sa);
  3335. if (remoteSystemLookup[index].index==(unsigned int)-1)
  3336. return (unsigned int) -1;
  3337. while (remoteSystemList[remoteSystemLookup[index].index].systemAddress!=sa)
  3338. {
  3339. if (++index==(unsigned int) maximumNumberOfPeers*REMOTE_SYSTEM_LOOKUP_HASH_MULTIPLE)
  3340. index=0;
  3341. if (++scanCount>(unsigned int) maximumNumberOfPeers*REMOTE_SYSTEM_LOOKUP_HASH_MULTIPLE)
  3342. return (unsigned int) -1;
  3343. if (remoteSystemLookup[index].index==-1)
  3344. return (unsigned int) -1;
  3345. }
  3346. return index;
  3347. }
  3348. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3349. unsigned int RakPeer::RemoteSystemListIndexUsingHashIndex(const SystemAddress &sa) const
  3350. {
  3351. unsigned int index = LookupIndexUsingHashIndex(sa);
  3352. if (index!=(unsigned int) -1)
  3353. {
  3354. return remoteSystemLookup[index].index;
  3355. }
  3356. return (unsigned int) -1;
  3357. }
  3358. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3359. unsigned int RakPeer::FirstFreeRemoteSystemLookupIndex(const SystemAddress &sa) const
  3360. {
  3361. // unsigned int collisionCount=0;
  3362. unsigned int index = RemoteSystemLookupHashIndex(sa);
  3363. while (remoteSystemLookup[index].index!=(unsigned int)-1)
  3364. {
  3365. if (++index==(unsigned int) maximumNumberOfPeers*REMOTE_SYSTEM_LOOKUP_HASH_MULTIPLE)
  3366. index=0;
  3367. // collisionCount++;
  3368. }
  3369. // printf("%i collisions. Using index %i\n", collisionCount, index);
  3370. return index;
  3371. }
  3372. */
  3373. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3374. bool RakPeer::IsLoopbackAddress(const AddressOrGUID &systemIdentifier, bool matchPort) const
  3375. {
  3376. if (systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID)
  3377. return systemIdentifier.rakNetGuid==myGuid;
  3378. for (int i=0; i < MAXIMUM_NUMBER_OF_INTERNAL_IDS && ipList[i]!=UNASSIGNED_SYSTEM_ADDRESS; i++)
  3379. {
  3380. if (matchPort)
  3381. {
  3382. if (ipList[i]==systemIdentifier.systemAddress)
  3383. return true;
  3384. }
  3385. else
  3386. {
  3387. if (ipList[i].EqualsExcludingPort(systemIdentifier.systemAddress))
  3388. return true;
  3389. }
  3390. }
  3391. return (matchPort==true && systemIdentifier.systemAddress==firstExternalID) ||
  3392. (matchPort==false && systemIdentifier.systemAddress.EqualsExcludingPort(firstExternalID));
  3393. }
  3394. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3395. SystemAddress RakPeer::GetLoopbackAddress(void) const
  3396. {
  3397. return ipList[0];
  3398. }
  3399. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3400. bool RakPeer::AllowIncomingConnections(void) const
  3401. {
  3402. return GetNumberOfRemoteInitiatedConnections() < GetMaximumIncomingConnections();
  3403. }
  3404. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3405. void RakPeer::DeallocRNS2RecvStruct(RNS2RecvStruct *s, const char *file, unsigned int line)
  3406. {
  3407. bufferedPacketsFreePoolMutex.Lock();
  3408. bufferedPacketsFreePool.Push(s, file, line);
  3409. bufferedPacketsFreePoolMutex.Unlock();
  3410. }
  3411. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3412. RNS2RecvStruct *RakPeer::AllocRNS2RecvStruct(const char *file, unsigned int line)
  3413. {
  3414. bufferedPacketsFreePoolMutex.Lock();
  3415. if (bufferedPacketsFreePool.Size()>0)
  3416. {
  3417. RNS2RecvStruct *s = bufferedPacketsFreePool.Pop();
  3418. bufferedPacketsFreePoolMutex.Unlock();
  3419. return s;
  3420. }
  3421. else
  3422. {
  3423. bufferedPacketsFreePoolMutex.Unlock();
  3424. return RakNet::OP_NEW<RNS2RecvStruct>(file,line);
  3425. }
  3426. }
  3427. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3428. void RakPeer::ClearBufferedPackets(void)
  3429. {
  3430. bufferedPacketsFreePoolMutex.Lock();
  3431. while (bufferedPacketsFreePool.Size()>0)
  3432. RakNet::OP_DELETE(bufferedPacketsFreePool.Pop(), _FILE_AND_LINE_);
  3433. bufferedPacketsFreePoolMutex.Unlock();
  3434. bufferedPacketsQueueMutex.Lock();
  3435. while (bufferedPacketsQueue.Size()>0)
  3436. RakNet::OP_DELETE(bufferedPacketsQueue.Pop(), _FILE_AND_LINE_);
  3437. bufferedPacketsQueueMutex.Unlock();
  3438. }
  3439. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3440. void RakPeer::SetupBufferedPackets(void)
  3441. {
  3442. }
  3443. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3444. void RakPeer::PushBufferedPacket(RNS2RecvStruct * p)
  3445. {
  3446. bufferedPacketsQueueMutex.Lock();
  3447. bufferedPacketsQueue.Push(p, _FILE_AND_LINE_);
  3448. bufferedPacketsQueueMutex.Unlock();
  3449. }
  3450. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3451. RNS2RecvStruct *RakPeer::PopBufferedPacket(void)
  3452. {
  3453. bufferedPacketsQueueMutex.Lock();
  3454. if (bufferedPacketsQueue.Size()>0)
  3455. {
  3456. RNS2RecvStruct *s = bufferedPacketsQueue.Pop();
  3457. bufferedPacketsQueueMutex.Unlock();
  3458. return s;
  3459. }
  3460. bufferedPacketsQueueMutex.Unlock();
  3461. return 0;
  3462. }
  3463. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3464. void RakPeer::PingInternal( const SystemAddress target, bool performImmediate, PacketReliability reliability )
  3465. {
  3466. if ( IsActive() == false )
  3467. return ;
  3468. RakNet::BitStream bitStream(sizeof(unsigned char)+sizeof(RakNet::Time));
  3469. bitStream.Write((MessageID)ID_CONNECTED_PING);
  3470. bitStream.Write(RakNet::GetTime());
  3471. if (performImmediate)
  3472. SendImmediate( (char*)bitStream.GetData(), bitStream.GetNumberOfBitsUsed(), IMMEDIATE_PRIORITY, reliability, 0, target, false, false, RakNet::GetTimeUS(), 0 );
  3473. else
  3474. Send( &bitStream, IMMEDIATE_PRIORITY, reliability, 0, target, false );
  3475. }
  3476. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3477. void RakPeer::CloseConnectionInternal( const AddressOrGUID& systemIdentifier, bool sendDisconnectionNotification, bool performImmediate, unsigned char orderingChannel, PacketPriority disconnectionNotificationPriority )
  3478. {
  3479. #ifdef _DEBUG
  3480. RakAssert(orderingChannel < 32);
  3481. #endif
  3482. if (systemIdentifier.IsUndefined())
  3483. return;
  3484. if ( remoteSystemList == 0 || endThreads == true )
  3485. return;
  3486. SystemAddress target;
  3487. if (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS)
  3488. {
  3489. target=systemIdentifier.systemAddress;
  3490. }
  3491. else
  3492. {
  3493. target=GetSystemAddressFromGuid(systemIdentifier.rakNetGuid);
  3494. }
  3495. if (target!=UNASSIGNED_SYSTEM_ADDRESS && performImmediate)
  3496. target.FixForIPVersion(socketList[0]->GetBoundAddress());
  3497. if (sendDisconnectionNotification)
  3498. {
  3499. NotifyAndFlagForShutdown(target, performImmediate, orderingChannel, disconnectionNotificationPriority);
  3500. }
  3501. else
  3502. {
  3503. if (performImmediate)
  3504. {
  3505. unsigned int index = GetRemoteSystemIndex(target);
  3506. if (index!=(unsigned int) -1)
  3507. {
  3508. if ( remoteSystemList[index].isActive )
  3509. {
  3510. RemoveFromActiveSystemList(target);
  3511. // Found the index to stop
  3512. // printf("--- Address %s has become inactive\n", remoteSystemList[index].systemAddress.ToString());
  3513. remoteSystemList[index].isActive = false;
  3514. remoteSystemList[index].guid=UNASSIGNED_RAKNET_GUID;
  3515. // Reserve this reliability layer for ourselves
  3516. //remoteSystemList[ remoteSystemLookup[index].index ].systemAddress = UNASSIGNED_SYSTEM_ADDRESS;
  3517. // Clear any remaining messages
  3518. RakAssert(remoteSystemList[index].MTUSize <= MAXIMUM_MTU_SIZE);
  3519. remoteSystemList[index].reliabilityLayer.Reset(false, remoteSystemList[index].MTUSize, false);
  3520. // Not using this socket
  3521. remoteSystemList[index].rakNetSocket = 0;
  3522. }
  3523. }
  3524. }
  3525. else
  3526. {
  3527. BufferedCommandStruct *bcs;
  3528. bcs=bufferedCommands.Allocate( _FILE_AND_LINE_ );
  3529. bcs->command=BufferedCommandStruct::BCS_CLOSE_CONNECTION;
  3530. bcs->systemIdentifier=target;
  3531. bcs->data=0;
  3532. bcs->orderingChannel=orderingChannel;
  3533. bcs->priority=disconnectionNotificationPriority;
  3534. bufferedCommands.Push(bcs);
  3535. }
  3536. }
  3537. }
  3538. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3539. void RakPeer::SendBuffered( const char *data, BitSize_t numberOfBitsToSend, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, RemoteSystemStruct::ConnectMode connectionMode, uint32_t receipt )
  3540. {
  3541. BufferedCommandStruct *bcs;
  3542. bcs=bufferedCommands.Allocate( _FILE_AND_LINE_ );
  3543. bcs->data = (char*) rakMalloc_Ex( (size_t) BITS_TO_BYTES(numberOfBitsToSend), _FILE_AND_LINE_ ); // Making a copy doesn't lose efficiency because I tell the reliability layer to use this allocation for its own copy
  3544. if (bcs->data==0)
  3545. {
  3546. notifyOutOfMemory(_FILE_AND_LINE_);
  3547. bufferedCommands.Deallocate(bcs, _FILE_AND_LINE_);
  3548. return;
  3549. }
  3550. RakAssert( !( reliability >= NUMBER_OF_RELIABILITIES || reliability < 0 ) );
  3551. RakAssert( !( priority > NUMBER_OF_PRIORITIES || priority < 0 ) );
  3552. RakAssert( !( orderingChannel >= NUMBER_OF_ORDERED_STREAMS ) );
  3553. memcpy(bcs->data, data, (size_t) BITS_TO_BYTES(numberOfBitsToSend));
  3554. bcs->numberOfBitsToSend=numberOfBitsToSend;
  3555. bcs->priority=priority;
  3556. bcs->reliability=reliability;
  3557. bcs->orderingChannel=orderingChannel;
  3558. bcs->systemIdentifier=systemIdentifier;
  3559. bcs->broadcast=broadcast;
  3560. bcs->connectionMode=connectionMode;
  3561. bcs->receipt=receipt;
  3562. bcs->command=BufferedCommandStruct::BCS_SEND;
  3563. bufferedCommands.Push(bcs);
  3564. if (priority==IMMEDIATE_PRIORITY)
  3565. {
  3566. // Forces pending sends to go out now, rather than waiting to the next update interval
  3567. quitAndDataEvents.SetEvent();
  3568. }
  3569. }
  3570. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3571. void RakPeer::SendBufferedList( const char **data, const int *lengths, const int numParameters, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, RemoteSystemStruct::ConnectMode connectionMode, uint32_t receipt )
  3572. {
  3573. BufferedCommandStruct *bcs;
  3574. unsigned int totalLength=0;
  3575. unsigned int lengthOffset;
  3576. int i;
  3577. for (i=0; i < numParameters; i++)
  3578. {
  3579. if (lengths[i]>0)
  3580. totalLength+=lengths[i];
  3581. }
  3582. if (totalLength==0)
  3583. return;
  3584. char *dataAggregate;
  3585. dataAggregate = (char*) rakMalloc_Ex( (size_t) totalLength, _FILE_AND_LINE_ ); // Making a copy doesn't lose efficiency because I tell the reliability layer to use this allocation for its own copy
  3586. if (dataAggregate==0)
  3587. {
  3588. notifyOutOfMemory(_FILE_AND_LINE_);
  3589. return;
  3590. }
  3591. for (i=0, lengthOffset=0; i < numParameters; i++)
  3592. {
  3593. if (lengths[i]>0)
  3594. {
  3595. memcpy(dataAggregate+lengthOffset, data[i], lengths[i]);
  3596. lengthOffset+=lengths[i];
  3597. }
  3598. }
  3599. if (broadcast==false && IsLoopbackAddress(systemIdentifier,true))
  3600. {
  3601. SendLoopback(dataAggregate,totalLength);
  3602. rakFree_Ex(dataAggregate,_FILE_AND_LINE_);
  3603. return;
  3604. }
  3605. RakAssert( !( reliability >= NUMBER_OF_RELIABILITIES || reliability < 0 ) );
  3606. RakAssert( !( priority > NUMBER_OF_PRIORITIES || priority < 0 ) );
  3607. RakAssert( !( orderingChannel >= NUMBER_OF_ORDERED_STREAMS ) );
  3608. bcs=bufferedCommands.Allocate( _FILE_AND_LINE_ );
  3609. bcs->data = dataAggregate;
  3610. bcs->numberOfBitsToSend=BYTES_TO_BITS(totalLength);
  3611. bcs->priority=priority;
  3612. bcs->reliability=reliability;
  3613. bcs->orderingChannel=orderingChannel;
  3614. bcs->systemIdentifier=systemIdentifier;
  3615. bcs->broadcast=broadcast;
  3616. bcs->connectionMode=connectionMode;
  3617. bcs->receipt=receipt;
  3618. bcs->command=BufferedCommandStruct::BCS_SEND;
  3619. bufferedCommands.Push(bcs);
  3620. if (priority==IMMEDIATE_PRIORITY)
  3621. {
  3622. // Forces pending sends to go out now, rather than waiting to the next update interval
  3623. quitAndDataEvents.SetEvent();
  3624. }
  3625. }
  3626. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3627. bool RakPeer::SendImmediate( char *data, BitSize_t numberOfBitsToSend, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, bool useCallerDataAllocation, RakNet::TimeUS currentTime, uint32_t receipt )
  3628. {
  3629. unsigned *sendList;
  3630. unsigned sendListSize;
  3631. bool callerDataAllocationUsed;
  3632. unsigned int remoteSystemIndex, sendListIndex; // Iterates into the list of remote systems
  3633. // unsigned numberOfBytesUsed = (unsigned) BITS_TO_BYTES(numberOfBitsToSend);
  3634. callerDataAllocationUsed=false;
  3635. sendListSize=0;
  3636. if (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS)
  3637. remoteSystemIndex=GetIndexFromSystemAddress( systemIdentifier.systemAddress, true );
  3638. else if (systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID)
  3639. remoteSystemIndex=GetSystemIndexFromGuid(systemIdentifier.rakNetGuid);
  3640. else
  3641. remoteSystemIndex=(unsigned int) -1;
  3642. // 03/06/06 - If broadcast is false, use the optimized version of GetIndexFromSystemAddress
  3643. if (broadcast==false)
  3644. {
  3645. if (remoteSystemIndex==(unsigned int) -1)
  3646. {
  3647. #ifdef _DEBUG
  3648. // int debugIndex = GetRemoteSystemIndex(systemIdentifier.systemAddress);
  3649. #endif
  3650. return false;
  3651. }
  3652. #if USE_ALLOCA==1
  3653. sendList=(unsigned *)alloca(sizeof(unsigned));
  3654. #else
  3655. sendList = (unsigned *) rakMalloc_Ex(sizeof(unsigned), _FILE_AND_LINE_);
  3656. #endif
  3657. if (remoteSystemList[remoteSystemIndex].isActive &&
  3658. remoteSystemList[remoteSystemIndex].connectMode!=RemoteSystemStruct::DISCONNECT_ASAP &&
  3659. remoteSystemList[remoteSystemIndex].connectMode!=RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY &&
  3660. remoteSystemList[remoteSystemIndex].connectMode!=RemoteSystemStruct::DISCONNECT_ON_NO_ACK)
  3661. {
  3662. sendList[0]=remoteSystemIndex;
  3663. sendListSize=1;
  3664. }
  3665. }
  3666. else
  3667. {
  3668. #if USE_ALLOCA==1
  3669. sendList=(unsigned *)alloca(sizeof(unsigned)*maximumNumberOfPeers);
  3670. #else
  3671. sendList = (unsigned *) rakMalloc_Ex(sizeof(unsigned)*maximumNumberOfPeers, _FILE_AND_LINE_);
  3672. #endif
  3673. // remoteSystemList in network thread
  3674. unsigned int idx;
  3675. for ( idx = 0; idx < maximumNumberOfPeers; idx++ )
  3676. {
  3677. if (remoteSystemIndex!=(unsigned int) -1 && idx==remoteSystemIndex)
  3678. continue;
  3679. if ( remoteSystemList[ idx ].isActive && remoteSystemList[ idx ].systemAddress != UNASSIGNED_SYSTEM_ADDRESS )
  3680. sendList[sendListSize++]=idx;
  3681. }
  3682. }
  3683. if (sendListSize==0)
  3684. {
  3685. #if !defined(USE_ALLOCA)
  3686. rakFree_Ex(sendList, _FILE_AND_LINE_ );
  3687. #endif
  3688. return false;
  3689. }
  3690. for (sendListIndex=0; sendListIndex < sendListSize; sendListIndex++)
  3691. {
  3692. // Send may split the packet and thus deallocate data. Don't assume data is valid if we use the callerAllocationData
  3693. bool useData = useCallerDataAllocation && callerDataAllocationUsed==false && sendListIndex+1==sendListSize;
  3694. remoteSystemList[sendList[sendListIndex]].reliabilityLayer.Send( data, numberOfBitsToSend, priority, reliability, orderingChannel, useData==false, remoteSystemList[sendList[sendListIndex]].MTUSize, currentTime, receipt );
  3695. if (useData)
  3696. callerDataAllocationUsed=true;
  3697. if (reliability==RELIABLE ||
  3698. reliability==RELIABLE_ORDERED ||
  3699. reliability==RELIABLE_SEQUENCED ||
  3700. reliability==RELIABLE_WITH_ACK_RECEIPT ||
  3701. reliability==RELIABLE_ORDERED_WITH_ACK_RECEIPT
  3702. // ||
  3703. // reliability==RELIABLE_SEQUENCED_WITH_ACK_RECEIPT
  3704. )
  3705. remoteSystemList[sendList[sendListIndex]].lastReliableSend=(RakNet::TimeMS)(currentTime/(RakNet::TimeUS)1000);
  3706. }
  3707. #if !defined(USE_ALLOCA)
  3708. rakFree_Ex(sendList, _FILE_AND_LINE_ );
  3709. #endif
  3710. // Return value only meaningful if true was passed for useCallerDataAllocation. Means the reliability layer used that data copy, so the caller should not deallocate it
  3711. return callerDataAllocationUsed;
  3712. }
  3713. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3714. void RakPeer::ResetSendReceipt(void)
  3715. {
  3716. sendReceiptSerialMutex.Lock();
  3717. sendReceiptSerial=1;
  3718. sendReceiptSerialMutex.Unlock();
  3719. }
  3720. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3721. void RakPeer::OnConnectedPong(RakNet::Time sendPingTime, RakNet::Time sendPongTime, RemoteSystemStruct *remoteSystem)
  3722. {
  3723. RakNet::Time ping;
  3724. // RakNet::TimeMS lastPing;
  3725. RakNet::Time time = RakNet::GetTime(); // Update the time value to be accurate
  3726. if (time > sendPingTime)
  3727. ping = time - sendPingTime;
  3728. else
  3729. ping=0;
  3730. // lastPing = remoteSystem->pingAndClockDifferential[ remoteSystem->pingAndClockDifferentialWriteIndex ].pingTime;
  3731. remoteSystem->pingAndClockDifferential[ remoteSystem->pingAndClockDifferentialWriteIndex ].pingTime = ( unsigned short ) ping;
  3732. // Thanks to Chris Taylor (cat02e@fsu.edu) for the improved timestamping algorithm
  3733. // Divide each integer by 2, rather than the sum by 2, to prevent overflow
  3734. remoteSystem->pingAndClockDifferential[ remoteSystem->pingAndClockDifferentialWriteIndex ].clockDifferential = sendPongTime - ( time/2 + sendPingTime/2 );
  3735. if ( remoteSystem->lowestPing == (unsigned short)-1 || remoteSystem->lowestPing > (int) ping )
  3736. remoteSystem->lowestPing = (unsigned short) ping;
  3737. if ( ++( remoteSystem->pingAndClockDifferentialWriteIndex ) == (RakNet::Time) PING_TIMES_ARRAY_SIZE )
  3738. remoteSystem->pingAndClockDifferentialWriteIndex = 0;
  3739. }
  3740. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3741. void RakPeer::ClearBufferedCommands(void)
  3742. {
  3743. BufferedCommandStruct *bcs;
  3744. while ((bcs=bufferedCommands.Pop())!=0)
  3745. {
  3746. if (bcs->data)
  3747. rakFree_Ex(bcs->data, _FILE_AND_LINE_ );
  3748. bufferedCommands.Deallocate(bcs, _FILE_AND_LINE_);
  3749. }
  3750. bufferedCommands.Clear(_FILE_AND_LINE_);
  3751. }
  3752. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3753. void RakPeer::ClearSocketQueryOutput(void)
  3754. {
  3755. socketQueryOutput.Clear(_FILE_AND_LINE_);
  3756. }
  3757. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3758. void RakPeer::ClearRequestedConnectionList(void)
  3759. {
  3760. DataStructures::Queue<RequestedConnectionStruct*> freeQueue;
  3761. requestedConnectionQueueMutex.Lock();
  3762. while (requestedConnectionQueue.Size())
  3763. freeQueue.Push(requestedConnectionQueue.Pop(), _FILE_AND_LINE_ );
  3764. requestedConnectionQueueMutex.Unlock();
  3765. unsigned i;
  3766. for (i=0; i < freeQueue.Size(); i++)
  3767. {
  3768. #if LIBCAT_SECURITY==1
  3769. CAT_AUDIT_PRINTF("AUDIT: In ClearRequestedConnectionList(), Deleting freeQueue index %i client_handshake %x\n", i, freeQueue[i]->client_handshake);
  3770. RakNet::OP_DELETE(freeQueue[i]->client_handshake,_FILE_AND_LINE_);
  3771. #endif
  3772. RakNet::OP_DELETE(freeQueue[i], _FILE_AND_LINE_ );
  3773. }
  3774. }
  3775. inline void RakPeer::AddPacketToProducer(RakNet::Packet *p)
  3776. {
  3777. packetReturnMutex.Lock();
  3778. packetReturnQueue.Push(p,_FILE_AND_LINE_);
  3779. packetReturnMutex.Unlock();
  3780. }
  3781. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3782. union Buff6AndBuff8
  3783. {
  3784. unsigned char buff6[6];
  3785. uint64_t buff8;
  3786. };
  3787. uint64_t RakPeerInterface::Get64BitUniqueRandomNumber(void)
  3788. {
  3789. // Mac address is a poor solution because you can't have multiple connections from the same system
  3790. #if defined(_WIN32)
  3791. uint64_t g=RakNet::GetTimeUS();
  3792. RakNet::TimeUS lastTime, thisTime;
  3793. int j;
  3794. // Sleep a small random time, then use the last 4 bits as a source of randomness
  3795. for (j=0; j < 8; j++)
  3796. {
  3797. lastTime = RakNet::GetTimeUS();
  3798. RakSleep(1);
  3799. RakSleep(0);
  3800. thisTime = RakNet::GetTimeUS();
  3801. RakNet::TimeUS diff = thisTime-lastTime;
  3802. unsigned int diff4Bits = (unsigned int) (diff & 15);
  3803. diff4Bits <<= 32-4;
  3804. diff4Bits >>= j*4;
  3805. ((char*)&g)[j] ^= diff4Bits;
  3806. }
  3807. return g;
  3808. #else
  3809. struct timeval tv;
  3810. gettimeofday(&tv, NULL);
  3811. return tv.tv_usec + tv.tv_sec * 1000000;
  3812. #endif
  3813. }
  3814. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3815. void RakPeer::GenerateGUID(void)
  3816. {
  3817. myGuid.g=Get64BitUniqueRandomNumber();
  3818. }
  3819. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3820. // void RakNet::ProcessPortUnreachable( SystemAddress systemAddress, RakPeer *rakPeer )
  3821. // {
  3822. // (void) binaryAddress;
  3823. // (void) port;
  3824. // (void) rakPeer;
  3825. //
  3826. // }
  3827. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  3828. namespace RakNet {
  3829. bool ProcessOfflineNetworkPacket( SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, RakNetSocket2* rakNetSocket, bool *isOfflineMessage, RakNet::TimeUS timeRead )
  3830. {
  3831. (void) timeRead;
  3832. RakPeer::RemoteSystemStruct *remoteSystem;
  3833. RakNet::Packet *packet;
  3834. unsigned i;
  3835. char str1[64];
  3836. systemAddress.ToString(false, str1);
  3837. if (rakPeer->IsBanned( str1 ))
  3838. {
  3839. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  3840. rakPeer->pluginListNTS[i]->OnDirectSocketReceive(data, length*8, systemAddress);
  3841. RakNet::BitStream bs;
  3842. bs.Write((MessageID)ID_CONNECTION_BANNED);
  3843. bs.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  3844. bs.Write(rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
  3845. RNS2_SendParameters bsp;
  3846. bsp.data = (char*) bs.GetData();
  3847. bsp.length = bs.GetNumberOfBytesUsed();
  3848. bsp.systemAddress = systemAddress;
  3849. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  3850. rakPeer->pluginListNTS[i]->OnDirectSocketSend((char*) bs.GetData(), bs.GetNumberOfBitsUsed(), systemAddress);
  3851. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  3852. /*
  3853. unsigned i;
  3854. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  3855. rakPeer->pluginListNTS[i]->OnDirectSocketSend((char*) bs.GetData(), bs.GetNumberOfBitsUsed(), systemAddress);
  3856. SocketLayer::SendTo( rakNetSocket, (char*) bs.GetData(), bs.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  3857. */
  3858. return true;
  3859. }
  3860. // The reason for all this is that the reliability layer has no way to tell between offline messages that arrived late for a player that is now connected,
  3861. // and a regular encoding. So I insert OFFLINE_MESSAGE_DATA_ID into the stream, the encoding of which is essentially impossible to hit by chance
  3862. if (length <=2)
  3863. {
  3864. *isOfflineMessage=true;
  3865. }
  3866. else if (
  3867. ((unsigned char)data[0] == ID_UNCONNECTED_PING ||
  3868. (unsigned char)data[0] == ID_UNCONNECTED_PING_OPEN_CONNECTIONS) &&
  3869. length >= sizeof(unsigned char) + sizeof(RakNet::Time) + sizeof(OFFLINE_MESSAGE_DATA_ID))
  3870. {
  3871. *isOfflineMessage=memcmp(data+sizeof(unsigned char) + sizeof(RakNet::Time), OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID))==0;
  3872. }
  3873. else if ((unsigned char)data[0] == ID_UNCONNECTED_PONG && (size_t) length >= sizeof(unsigned char) + sizeof(RakNet::TimeMS) + RakNetGUID::size() + sizeof(OFFLINE_MESSAGE_DATA_ID))
  3874. {
  3875. *isOfflineMessage=memcmp(data+sizeof(unsigned char) + sizeof(RakNet::Time) + RakNetGUID::size(), OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID))==0;
  3876. }
  3877. else if (
  3878. (unsigned char)data[0] == ID_OUT_OF_BAND_INTERNAL &&
  3879. (size_t) length >= sizeof(MessageID) + RakNetGUID::size() + sizeof(OFFLINE_MESSAGE_DATA_ID))
  3880. {
  3881. *isOfflineMessage=memcmp(data+sizeof(MessageID) + RakNetGUID::size(), OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID))==0;
  3882. }
  3883. else if (
  3884. (
  3885. (unsigned char)data[0] == ID_OPEN_CONNECTION_REPLY_1 ||
  3886. (unsigned char)data[0] == ID_OPEN_CONNECTION_REPLY_2 ||
  3887. (unsigned char)data[0] == ID_OPEN_CONNECTION_REQUEST_1 ||
  3888. (unsigned char)data[0] == ID_OPEN_CONNECTION_REQUEST_2 ||
  3889. (unsigned char)data[0] == ID_CONNECTION_ATTEMPT_FAILED ||
  3890. (unsigned char)data[0] == ID_NO_FREE_INCOMING_CONNECTIONS ||
  3891. (unsigned char)data[0] == ID_CONNECTION_BANNED ||
  3892. (unsigned char)data[0] == ID_ALREADY_CONNECTED ||
  3893. (unsigned char)data[0] == ID_IP_RECENTLY_CONNECTED) &&
  3894. (size_t) length >= sizeof(MessageID) + RakNetGUID::size() + sizeof(OFFLINE_MESSAGE_DATA_ID))
  3895. {
  3896. *isOfflineMessage=memcmp(data+sizeof(MessageID), OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID))==0;
  3897. }
  3898. else if (((unsigned char)data[0] == ID_INCOMPATIBLE_PROTOCOL_VERSION&&
  3899. (size_t) length == sizeof(MessageID)*2 + RakNetGUID::size() + sizeof(OFFLINE_MESSAGE_DATA_ID)))
  3900. {
  3901. *isOfflineMessage=memcmp(data+sizeof(MessageID)*2, OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID))==0;
  3902. }
  3903. else
  3904. {
  3905. *isOfflineMessage=false;
  3906. }
  3907. if (*isOfflineMessage)
  3908. {
  3909. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  3910. rakPeer->pluginListNTS[i]->OnDirectSocketReceive(data, length*8, systemAddress);
  3911. // These are all messages from unconnected systems. Messages here can be any size, but are never processed from connected systems.
  3912. if ( ( (unsigned char) data[ 0 ] == ID_UNCONNECTED_PING_OPEN_CONNECTIONS
  3913. || (unsigned char)(data)[0] == ID_UNCONNECTED_PING) && length >= sizeof(unsigned char)+sizeof(RakNet::Time)+sizeof(OFFLINE_MESSAGE_DATA_ID) )
  3914. {
  3915. if ( (unsigned char)(data)[0] == ID_UNCONNECTED_PING ||
  3916. rakPeer->AllowIncomingConnections() ) // Open connections with players
  3917. {
  3918. RakNet::BitStream inBitStream( (unsigned char *) data, length, false );
  3919. inBitStream.IgnoreBits(8);
  3920. RakNet::Time sendPingTime;
  3921. inBitStream.Read(sendPingTime);
  3922. inBitStream.IgnoreBytes(sizeof(OFFLINE_MESSAGE_DATA_ID));
  3923. RakNetGUID remoteGuid=UNASSIGNED_RAKNET_GUID;
  3924. inBitStream.Read(remoteGuid);
  3925. RakNet::BitStream outBitStream;
  3926. outBitStream.Write((MessageID)ID_UNCONNECTED_PONG); // Should be named ID_UNCONNECTED_PONG eventually
  3927. outBitStream.Write(sendPingTime);
  3928. outBitStream.Write(rakPeer->myGuid);
  3929. outBitStream.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  3930. rakPeer->rakPeerMutexes[ RakPeer::offlinePingResponse_Mutex ].Lock();
  3931. // They are connected, so append offline ping data
  3932. outBitStream.Write( (char*)rakPeer->offlinePingResponse.GetData(), rakPeer->offlinePingResponse.GetNumberOfBytesUsed() );
  3933. rakPeer->rakPeerMutexes[ RakPeer::offlinePingResponse_Mutex ].Unlock();
  3934. unsigned i;
  3935. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  3936. rakPeer->pluginListNTS[i]->OnDirectSocketSend((const char*)outBitStream.GetData(), outBitStream.GetNumberOfBytesUsed(), systemAddress);
  3937. RNS2_SendParameters bsp;
  3938. bsp.data = (char*) outBitStream.GetData();
  3939. bsp.length = outBitStream.GetNumberOfBytesUsed();
  3940. bsp.systemAddress = systemAddress;
  3941. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  3942. // SocketLayer::SendTo( rakNetSocket, (const char*)outBitStream.GetData(), (unsigned int) outBitStream.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  3943. packet=rakPeer->AllocPacket(sizeof(MessageID), _FILE_AND_LINE_);
  3944. packet->data[0]=data[0];
  3945. packet->systemAddress = systemAddress;
  3946. packet->guid=remoteGuid;
  3947. packet->systemAddress.systemIndex = ( SystemIndex ) rakPeer->GetIndexFromSystemAddress( systemAddress, true );
  3948. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  3949. rakPeer->AddPacketToProducer(packet);
  3950. }
  3951. }
  3952. // UNCONNECTED MESSAGE Pong with no data.
  3953. else if ((unsigned char) data[ 0 ] == ID_UNCONNECTED_PONG && (size_t) length >= sizeof(unsigned char)+sizeof(RakNet::Time)+RakNetGUID::size()+sizeof(OFFLINE_MESSAGE_DATA_ID) && (size_t) length < sizeof(unsigned char)+sizeof(RakNet::Time)+RakNetGUID::size()+sizeof(OFFLINE_MESSAGE_DATA_ID)+MAX_OFFLINE_DATA_LENGTH)
  3954. {
  3955. packet=rakPeer->AllocPacket((unsigned int) (length-sizeof(OFFLINE_MESSAGE_DATA_ID)-RakNetGUID::size()-sizeof(RakNet::Time)+sizeof(RakNet::TimeMS)), _FILE_AND_LINE_);
  3956. RakNet::BitStream bsIn((unsigned char*) data, length, false);
  3957. bsIn.IgnoreBytes(sizeof(unsigned char));
  3958. RakNet::Time ping;
  3959. bsIn.Read(ping);
  3960. bsIn.Read(packet->guid);
  3961. RakNet::BitStream bsOut((unsigned char*) packet->data, packet->length, false);
  3962. bsOut.ResetWritePointer();
  3963. bsOut.Write((unsigned char)ID_UNCONNECTED_PONG);
  3964. RakNet::TimeMS pingMS=(RakNet::TimeMS)ping;
  3965. bsOut.Write(pingMS);
  3966. bsOut.WriteAlignedBytes(
  3967. (const unsigned char*)data+sizeof(unsigned char)+sizeof(RakNet::Time)+RakNetGUID::size()+sizeof(OFFLINE_MESSAGE_DATA_ID),
  3968. length-sizeof(unsigned char)-sizeof(RakNet::Time)-RakNetGUID::size()-sizeof(OFFLINE_MESSAGE_DATA_ID)
  3969. );
  3970. packet->systemAddress = systemAddress;
  3971. packet->systemAddress.systemIndex = ( SystemIndex ) rakPeer->GetIndexFromSystemAddress( systemAddress, true );
  3972. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  3973. rakPeer->AddPacketToProducer(packet);
  3974. }
  3975. else if ((unsigned char) data[ 0 ] == ID_OUT_OF_BAND_INTERNAL &&
  3976. (size_t) length > sizeof(OFFLINE_MESSAGE_DATA_ID)+sizeof(MessageID)+RakNetGUID::size() &&
  3977. (size_t) length < MAX_OFFLINE_DATA_LENGTH+sizeof(OFFLINE_MESSAGE_DATA_ID)+sizeof(MessageID)+RakNetGUID::size())
  3978. {
  3979. unsigned int dataLength = (unsigned int) (length-sizeof(OFFLINE_MESSAGE_DATA_ID)-RakNetGUID::size()-sizeof(MessageID));
  3980. RakAssert(dataLength<1024);
  3981. packet=rakPeer->AllocPacket(dataLength+1, _FILE_AND_LINE_);
  3982. RakAssert(packet->length<1024);
  3983. RakNet::BitStream bs2((unsigned char*) data, length, false);
  3984. bs2.IgnoreBytes(sizeof(MessageID));
  3985. bs2.Read(packet->guid);
  3986. if (data[sizeof(OFFLINE_MESSAGE_DATA_ID)+sizeof(MessageID) + RakNetGUID::size()]==ID_ADVERTISE_SYSTEM)
  3987. {
  3988. packet->length--;
  3989. packet->bitSize=BYTES_TO_BITS(packet->length);
  3990. packet->data[0]=ID_ADVERTISE_SYSTEM;
  3991. memcpy(packet->data+1, data+sizeof(OFFLINE_MESSAGE_DATA_ID)+sizeof(MessageID)*2 + RakNetGUID::size(), dataLength-1);
  3992. }
  3993. else
  3994. {
  3995. packet->data[0]=ID_OUT_OF_BAND_INTERNAL;
  3996. memcpy(packet->data+1, data+sizeof(OFFLINE_MESSAGE_DATA_ID)+sizeof(MessageID) + RakNetGUID::size(), dataLength);
  3997. }
  3998. packet->systemAddress = systemAddress;
  3999. packet->systemAddress.systemIndex = ( SystemIndex ) rakPeer->GetIndexFromSystemAddress( systemAddress, true );
  4000. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  4001. rakPeer->AddPacketToProducer(packet);
  4002. }
  4003. else if ((unsigned char)(data)[0] == (MessageID)ID_OPEN_CONNECTION_REPLY_1)
  4004. {
  4005. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4006. rakPeer->pluginListNTS[i]->OnDirectSocketReceive(data, length*8, systemAddress);
  4007. RakNet::BitStream bsIn((unsigned char*) data,length,false);
  4008. bsIn.IgnoreBytes(sizeof(MessageID));
  4009. bsIn.IgnoreBytes(sizeof(OFFLINE_MESSAGE_DATA_ID));
  4010. RakNetGUID serverGuid;
  4011. bsIn.Read(serverGuid);
  4012. unsigned char serverHasSecurity;
  4013. uint32_t cookie;
  4014. (void) cookie;
  4015. bsIn.Read(serverHasSecurity);
  4016. // Even if the server has security, it may not be required of us if we are in the security exception list
  4017. if (serverHasSecurity)
  4018. {
  4019. bsIn.Read(cookie);
  4020. }
  4021. RakNet::BitStream bsOut;
  4022. bsOut.Write((MessageID)ID_OPEN_CONNECTION_REQUEST_2);
  4023. bsOut.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  4024. if (serverHasSecurity)
  4025. bsOut.Write(cookie);
  4026. unsigned i;
  4027. rakPeer->requestedConnectionQueueMutex.Lock();
  4028. for (i=0; i < rakPeer->requestedConnectionQueue.Size(); i++)
  4029. {
  4030. RakPeer::RequestedConnectionStruct *rcs;
  4031. rcs=rakPeer->requestedConnectionQueue[i];
  4032. if (rcs->systemAddress==systemAddress)
  4033. {
  4034. if (serverHasSecurity)
  4035. {
  4036. #if LIBCAT_SECURITY==1
  4037. unsigned char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
  4038. bsIn.ReadAlignedBytes(public_key, sizeof(public_key));
  4039. if (rcs->publicKeyMode==PKM_ACCEPT_ANY_PUBLIC_KEY)
  4040. {
  4041. memcpy(rcs->remote_public_key, public_key, cat::EasyHandshake::PUBLIC_KEY_BYTES);
  4042. if (!rcs->client_handshake->Initialize(public_key) ||
  4043. !rcs->client_handshake->GenerateChallenge(rcs->handshakeChallenge))
  4044. {
  4045. CAT_AUDIT_PRINTF("AUDIT: Server passed a bad public key with PKM_ACCEPT_ANY_PUBLIC_KEY");
  4046. return true;
  4047. }
  4048. }
  4049. if (cat::SecureEqual(public_key,
  4050. rcs->remote_public_key,
  4051. cat::EasyHandshake::PUBLIC_KEY_BYTES)==false)
  4052. {
  4053. rakPeer->requestedConnectionQueueMutex.Unlock();
  4054. CAT_AUDIT_PRINTF("AUDIT: Expected public key does not match what was sent by server -- Reporting back ID_PUBLIC_KEY_MISMATCH to user\n");
  4055. packet=rakPeer->AllocPacket(sizeof( char ), _FILE_AND_LINE_);
  4056. packet->data[ 0 ] = ID_PUBLIC_KEY_MISMATCH; // Attempted a connection and couldn't
  4057. packet->bitSize = ( sizeof( char ) * 8);
  4058. packet->systemAddress = rcs->systemAddress;
  4059. packet->guid=serverGuid;
  4060. rakPeer->AddPacketToProducer(packet);
  4061. return true;
  4062. }
  4063. if (rcs->client_handshake==0)
  4064. {
  4065. // Message does not contain a challenge
  4066. // We might still pass if we are in the security exception list
  4067. bsOut.Write((unsigned char)0);
  4068. }
  4069. else
  4070. {
  4071. // Message contains a challenge
  4072. bsOut.Write((unsigned char)1);
  4073. // challenge
  4074. CAT_AUDIT_PRINTF("AUDIT: Sending challenge\n");
  4075. bsOut.WriteAlignedBytes((const unsigned char*) rcs->handshakeChallenge,cat::EasyHandshake::CHALLENGE_BYTES);
  4076. }
  4077. #else // LIBCAT_SECURITY
  4078. // Message does not contain a challenge
  4079. bsOut.Write((unsigned char)0);
  4080. #endif // LIBCAT_SECURITY
  4081. }
  4082. else
  4083. {
  4084. // Server does not need security
  4085. #if LIBCAT_SECURITY==1
  4086. if (rcs->client_handshake!=0)
  4087. {
  4088. rakPeer->requestedConnectionQueueMutex.Unlock();
  4089. CAT_AUDIT_PRINTF("AUDIT: Security disabled by server but we expected security (indicated by client_handshake not null) so failing!\n");
  4090. packet=rakPeer->AllocPacket(sizeof( char ), _FILE_AND_LINE_);
  4091. packet->data[ 0 ] = ID_OUR_SYSTEM_REQUIRES_SECURITY; // Attempted a connection and couldn't
  4092. packet->bitSize = ( sizeof( char ) * 8);
  4093. packet->systemAddress = rcs->systemAddress;
  4094. packet->guid=serverGuid;
  4095. rakPeer->AddPacketToProducer(packet);
  4096. return true;
  4097. }
  4098. #endif // LIBCAT_SECURITY
  4099. }
  4100. uint16_t mtu;
  4101. bsIn.Read(mtu);
  4102. // Binding address
  4103. bsOut.Write(rcs->systemAddress);
  4104. rakPeer->requestedConnectionQueueMutex.Unlock();
  4105. // MTU
  4106. bsOut.Write(mtu);
  4107. // Our guid
  4108. bsOut.Write(rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
  4109. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4110. rakPeer->pluginListNTS[i]->OnDirectSocketSend((const char*) bsOut.GetData(), bsOut.GetNumberOfBitsUsed(), rcs->systemAddress);
  4111. // SocketLayer::SendTo( rakPeer->socketList[rcs->socketIndex], (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), rcs->systemAddress, _FILE_AND_LINE_ );
  4112. RNS2_SendParameters bsp;
  4113. bsp.data = (char*) bsOut.GetData();
  4114. bsp.length = bsOut.GetNumberOfBytesUsed();
  4115. bsp.systemAddress = systemAddress;
  4116. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  4117. return true;
  4118. }
  4119. }
  4120. rakPeer->requestedConnectionQueueMutex.Unlock();
  4121. }
  4122. else if ((unsigned char)(data)[0] == (MessageID)ID_OPEN_CONNECTION_REPLY_2)
  4123. {
  4124. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4125. rakPeer->pluginListNTS[i]->OnDirectSocketReceive(data, length*8, systemAddress);
  4126. RakNet::BitStream bs((unsigned char*) data,length,false);
  4127. bs.IgnoreBytes(sizeof(MessageID));
  4128. bs.IgnoreBytes(sizeof(OFFLINE_MESSAGE_DATA_ID));
  4129. RakNetGUID guid;
  4130. bs.Read(guid);
  4131. SystemAddress bindingAddress;
  4132. bool b = bs.Read(bindingAddress);
  4133. RakAssert(b);
  4134. uint16_t mtu;
  4135. b=bs.Read(mtu);
  4136. RakAssert(b);
  4137. bool doSecurity=false;
  4138. b=bs.Read(doSecurity);
  4139. RakAssert(b);
  4140. #if LIBCAT_SECURITY==1
  4141. char answer[cat::EasyHandshake::ANSWER_BYTES];
  4142. CAT_AUDIT_PRINTF("AUDIT: Got ID_OPEN_CONNECTION_REPLY_2 and given doSecurity=%i\n", (int)doSecurity);
  4143. if (doSecurity)
  4144. {
  4145. CAT_AUDIT_PRINTF("AUDIT: Reading cookie and public key\n");
  4146. bs.ReadAlignedBytes((unsigned char*) answer, sizeof(answer));
  4147. }
  4148. cat::ClientEasyHandshake *client_handshake=0;
  4149. #endif // LIBCAT_SECURITY
  4150. RakPeer::RequestedConnectionStruct *rcs;
  4151. bool unlock=true;
  4152. unsigned i;
  4153. rakPeer->requestedConnectionQueueMutex.Lock();
  4154. for (i=0; i < rakPeer->requestedConnectionQueue.Size(); i++)
  4155. {
  4156. rcs=rakPeer->requestedConnectionQueue[i];
  4157. if (rcs->systemAddress==systemAddress)
  4158. {
  4159. #if LIBCAT_SECURITY==1
  4160. CAT_AUDIT_PRINTF("AUDIT: System address matches an entry in the requestedConnectionQueue and doSecurity=%i\n", (int)doSecurity);
  4161. if (doSecurity)
  4162. {
  4163. if (rcs->client_handshake==0)
  4164. {
  4165. CAT_AUDIT_PRINTF("AUDIT: Server wants security but we didn't set a public key -- Reporting back ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY to user\n");
  4166. rakPeer->requestedConnectionQueueMutex.Unlock();
  4167. packet=rakPeer->AllocPacket(2, _FILE_AND_LINE_);
  4168. packet->data[ 0 ] = ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY; // Attempted a connection and couldn't
  4169. packet->data[ 1 ] = 0; // Indicate server public key is missing
  4170. packet->bitSize = ( sizeof( char ) * 8);
  4171. packet->systemAddress = rcs->systemAddress;
  4172. packet->guid=guid;
  4173. rakPeer->AddPacketToProducer(packet);
  4174. return true;
  4175. }
  4176. CAT_AUDIT_PRINTF("AUDIT: Looks good, preparing to send challenge to server! client_handshake = %x\n", client_handshake);
  4177. }
  4178. #endif // LIBCAT_SECURITY
  4179. rakPeer->requestedConnectionQueueMutex.Unlock();
  4180. unlock=false;
  4181. RakAssert(rcs->actionToTake==RakPeer::RequestedConnectionStruct::CONNECT);
  4182. // You might get this when already connected because of cross-connections
  4183. bool thisIPConnectedRecently=false;
  4184. remoteSystem=rakPeer->GetRemoteSystemFromSystemAddress( systemAddress, true, true );
  4185. if (remoteSystem==0)
  4186. {
  4187. if (rcs->socket == 0)
  4188. {
  4189. remoteSystem=rakPeer->AssignSystemAddressToRemoteSystemList(systemAddress, RakPeer::RemoteSystemStruct::UNVERIFIED_SENDER, rakNetSocket, &thisIPConnectedRecently, bindingAddress, mtu, guid, doSecurity);
  4190. }
  4191. else
  4192. {
  4193. remoteSystem=rakPeer->AssignSystemAddressToRemoteSystemList(systemAddress, RakPeer::RemoteSystemStruct::UNVERIFIED_SENDER, rcs->socket, &thisIPConnectedRecently, bindingAddress, mtu, guid, doSecurity);
  4194. }
  4195. }
  4196. // 4/13/09 Attackers can flood ID_OPEN_CONNECTION_REQUEST and use up all available connection slots
  4197. // Ignore connection attempts if this IP address connected within the last 100 milliseconds
  4198. if (thisIPConnectedRecently==false)
  4199. {
  4200. // Don't check GetRemoteSystemFromGUID, server will verify
  4201. if (remoteSystem)
  4202. {
  4203. // Move pointer from RequestedConnectionStruct to RemoteSystemStruct
  4204. #if LIBCAT_SECURITY==1
  4205. cat::u8 ident[cat::EasyHandshake::IDENTITY_BYTES];
  4206. bool doIdentity = false;
  4207. if (rcs->client_handshake)
  4208. {
  4209. CAT_AUDIT_PRINTF("AUDIT: Processing answer\n");
  4210. if (rcs->publicKeyMode == PKM_USE_TWO_WAY_AUTHENTICATION)
  4211. {
  4212. if (!rcs->client_handshake->ProcessAnswerWithIdentity(answer, ident, remoteSystem->reliabilityLayer.GetAuthenticatedEncryption()))
  4213. {
  4214. CAT_AUDIT_PRINTF("AUDIT: Processing answer -- Invalid Answer\n");
  4215. rakPeer->requestedConnectionQueueMutex.Unlock();
  4216. return true;
  4217. }
  4218. doIdentity = true;
  4219. }
  4220. else
  4221. {
  4222. if (!rcs->client_handshake->ProcessAnswer(answer, remoteSystem->reliabilityLayer.GetAuthenticatedEncryption()))
  4223. {
  4224. CAT_AUDIT_PRINTF("AUDIT: Processing answer -- Invalid Answer\n");
  4225. rakPeer->requestedConnectionQueueMutex.Unlock();
  4226. return true;
  4227. }
  4228. }
  4229. CAT_AUDIT_PRINTF("AUDIT: Success!\n");
  4230. RakNet::OP_DELETE(rcs->client_handshake,_FILE_AND_LINE_);
  4231. rcs->client_handshake=0;
  4232. }
  4233. #endif // LIBCAT_SECURITY
  4234. remoteSystem->weInitiatedTheConnection=true;
  4235. remoteSystem->connectMode=RakPeer::RemoteSystemStruct::REQUESTED_CONNECTION;
  4236. if (rcs->timeoutTime!=0)
  4237. remoteSystem->reliabilityLayer.SetTimeoutTime(rcs->timeoutTime);
  4238. RakNet::BitStream temp;
  4239. temp.Write( (MessageID)ID_CONNECTION_REQUEST);
  4240. temp.Write(rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
  4241. temp.Write(RakNet::GetTime());
  4242. #if LIBCAT_SECURITY==1
  4243. temp.Write((unsigned char)(doSecurity ? 1 : 0));
  4244. if (doSecurity)
  4245. {
  4246. unsigned char proof[32];
  4247. remoteSystem->reliabilityLayer.GetAuthenticatedEncryption()->GenerateProof(proof, sizeof(proof));
  4248. temp.WriteAlignedBytes(proof, sizeof(proof));
  4249. temp.Write((unsigned char)(doIdentity ? 1 : 0));
  4250. if (doIdentity)
  4251. {
  4252. temp.WriteAlignedBytes(ident, sizeof(ident));
  4253. }
  4254. }
  4255. #else
  4256. temp.Write((unsigned char)0);
  4257. #endif // LIBCAT_SECURITY
  4258. if ( rcs->outgoingPasswordLength > 0 )
  4259. temp.Write( ( char* ) rcs->outgoingPassword, rcs->outgoingPasswordLength );
  4260. rakPeer->SendImmediate((char*)temp.GetData(), temp.GetNumberOfBitsUsed(), IMMEDIATE_PRIORITY, RELIABLE, 0, systemAddress, false, false, timeRead, 0 );
  4261. }
  4262. else
  4263. {
  4264. // Failed, no connections available anymore
  4265. packet=rakPeer->AllocPacket(sizeof( char ), _FILE_AND_LINE_);
  4266. packet->data[ 0 ] = ID_CONNECTION_ATTEMPT_FAILED; // Attempted a connection and couldn't
  4267. packet->bitSize = ( sizeof( char ) * 8);
  4268. packet->systemAddress = rcs->systemAddress;
  4269. packet->guid=guid;
  4270. rakPeer->AddPacketToProducer(packet);
  4271. }
  4272. }
  4273. rakPeer->requestedConnectionQueueMutex.Lock();
  4274. for (unsigned int k=0; k < rakPeer->requestedConnectionQueue.Size(); k++)
  4275. {
  4276. if (rakPeer->requestedConnectionQueue[k]->systemAddress==systemAddress)
  4277. {
  4278. rakPeer->requestedConnectionQueue.RemoveAtIndex(k);
  4279. break;
  4280. }
  4281. }
  4282. rakPeer->requestedConnectionQueueMutex.Unlock();
  4283. #if LIBCAT_SECURITY==1
  4284. CAT_AUDIT_PRINTF("AUDIT: Deleting client_handshake object %x and rcs->client_handshake object %x\n", client_handshake, rcs->client_handshake);
  4285. RakNet::OP_DELETE(client_handshake,_FILE_AND_LINE_);
  4286. RakNet::OP_DELETE(rcs->client_handshake,_FILE_AND_LINE_);
  4287. #endif // LIBCAT_SECURITY
  4288. RakNet::OP_DELETE(rcs,_FILE_AND_LINE_);
  4289. break;
  4290. }
  4291. }
  4292. if (unlock)
  4293. rakPeer->requestedConnectionQueueMutex.Unlock();
  4294. return true;
  4295. }
  4296. else if ((unsigned char)(data)[0] == (MessageID)ID_CONNECTION_ATTEMPT_FAILED ||
  4297. (unsigned char)(data)[0] == (MessageID)ID_NO_FREE_INCOMING_CONNECTIONS ||
  4298. (unsigned char)(data)[0] == (MessageID)ID_CONNECTION_BANNED ||
  4299. (unsigned char)(data)[0] == (MessageID)ID_ALREADY_CONNECTED ||
  4300. (unsigned char)(data)[0] == (MessageID)ID_INVALID_PASSWORD ||
  4301. (unsigned char)(data)[0] == (MessageID)ID_IP_RECENTLY_CONNECTED ||
  4302. (unsigned char)(data)[0] == (MessageID)ID_INCOMPATIBLE_PROTOCOL_VERSION)
  4303. {
  4304. RakNet::BitStream bs((unsigned char*) data,length,false);
  4305. bs.IgnoreBytes(sizeof(MessageID));
  4306. bs.IgnoreBytes(sizeof(OFFLINE_MESSAGE_DATA_ID));
  4307. if ((unsigned char)(data)[0] == (MessageID)ID_INCOMPATIBLE_PROTOCOL_VERSION)
  4308. bs.IgnoreBytes(sizeof(unsigned char));
  4309. RakNetGUID guid;
  4310. bs.Read(guid);
  4311. RakPeer::RequestedConnectionStruct *rcs;
  4312. bool connectionAttemptCancelled=false;
  4313. unsigned i;
  4314. rakPeer->requestedConnectionQueueMutex.Lock();
  4315. for (i=0; i < rakPeer->requestedConnectionQueue.Size(); i++)
  4316. {
  4317. rcs=rakPeer->requestedConnectionQueue[i];
  4318. if (rcs->actionToTake==RakPeer::RequestedConnectionStruct::CONNECT && rcs->systemAddress==systemAddress)
  4319. {
  4320. connectionAttemptCancelled=true;
  4321. rakPeer->requestedConnectionQueue.RemoveAtIndex(i);
  4322. #if LIBCAT_SECURITY==1
  4323. CAT_AUDIT_PRINTF("AUDIT: Connection attempt canceled so deleting rcs->client_handshake object %x\n", rcs->client_handshake);
  4324. RakNet::OP_DELETE(rcs->client_handshake,_FILE_AND_LINE_);
  4325. #endif // LIBCAT_SECURITY
  4326. RakNet::OP_DELETE(rcs,_FILE_AND_LINE_);
  4327. break;
  4328. }
  4329. }
  4330. rakPeer->requestedConnectionQueueMutex.Unlock();
  4331. if (connectionAttemptCancelled)
  4332. {
  4333. // Tell user of connection attempt failed
  4334. packet=rakPeer->AllocPacket(sizeof( char ), _FILE_AND_LINE_);
  4335. packet->data[ 0 ] = data[0]; // Attempted a connection and couldn't
  4336. packet->bitSize = ( sizeof( char ) * 8);
  4337. packet->systemAddress = systemAddress;
  4338. packet->guid=guid;
  4339. rakPeer->AddPacketToProducer(packet);
  4340. }
  4341. }
  4342. else if ((unsigned char)(data)[0] == ID_OPEN_CONNECTION_REQUEST_1 && length > (int) (1+sizeof(OFFLINE_MESSAGE_DATA_ID)))
  4343. {/*
  4344. static int x = 0;
  4345. ++x;
  4346. SystemAddress *addr = (SystemAddress*)&systemAddress;
  4347. addr->binaryAddress += x;*/
  4348. unsigned int i;
  4349. //RAKNET_DEBUG_PRINTF("%i:IOCR, ", __LINE__);
  4350. char remoteProtocol=data[1+sizeof(OFFLINE_MESSAGE_DATA_ID)];
  4351. if (remoteProtocol!=RAKNET_PROTOCOL_VERSION)
  4352. {
  4353. RakNet::BitStream bs;
  4354. bs.Write((MessageID)ID_INCOMPATIBLE_PROTOCOL_VERSION);
  4355. bs.Write((unsigned char)RAKNET_PROTOCOL_VERSION);
  4356. bs.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  4357. bs.Write(rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
  4358. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4359. rakPeer->pluginListNTS[i]->OnDirectSocketSend((char*)bs.GetData(), bs.GetNumberOfBitsUsed(), systemAddress);
  4360. // SocketLayer::SendTo( rakNetSocket, (char*)bs.GetData(), bs.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  4361. RNS2_SendParameters bsp;
  4362. bsp.data = (char*) bs.GetData();
  4363. bsp.length = bs.GetNumberOfBytesUsed();
  4364. bsp.systemAddress = systemAddress;
  4365. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  4366. return true;
  4367. }
  4368. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4369. rakPeer->pluginListNTS[i]->OnDirectSocketReceive(data, length*8, systemAddress);
  4370. RakNet::BitStream bsOut;
  4371. bsOut.Write((MessageID)ID_OPEN_CONNECTION_REPLY_1);
  4372. bsOut.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  4373. bsOut.Write(rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
  4374. #if LIBCAT_SECURITY==1
  4375. if (rakPeer->_using_security)
  4376. {
  4377. bsOut.Write((unsigned char) 1); // HasCookie Yes
  4378. // Write cookie
  4379. uint32_t cookie = rakPeer->_cookie_jar->Generate(&systemAddress.address,sizeof(systemAddress.address));
  4380. CAT_AUDIT_PRINTF("AUDIT: Writing cookie %i to %i:%i\n", cookie, systemAddress);
  4381. bsOut.Write(cookie);
  4382. // Write my public key
  4383. bsOut.WriteAlignedBytes((const unsigned char *) rakPeer->my_public_key,sizeof(rakPeer->my_public_key));
  4384. }
  4385. else
  4386. #endif // LIBCAT_SECURITY
  4387. bsOut.Write((unsigned char) 0); // HasCookie oN
  4388. // MTU. Lower MTU if it is exceeds our own limit
  4389. if (length+UDP_HEADER_SIZE > MAXIMUM_MTU_SIZE)
  4390. bsOut.WriteCasted<uint16_t>(MAXIMUM_MTU_SIZE);
  4391. else
  4392. bsOut.WriteCasted<uint16_t>(length+UDP_HEADER_SIZE);
  4393. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4394. rakPeer->pluginListNTS[i]->OnDirectSocketSend((const char*) bsOut.GetData(), bsOut.GetNumberOfBitsUsed(), systemAddress);
  4395. // SocketLayer::SendTo( rakNetSocket, (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  4396. RNS2_SendParameters bsp;
  4397. bsp.data = (char*) bsOut.GetData();
  4398. bsp.length = bsOut.GetNumberOfBytesUsed();
  4399. bsp.systemAddress = systemAddress;
  4400. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  4401. }
  4402. else if ((unsigned char)(data)[0] == ID_OPEN_CONNECTION_REQUEST_2)
  4403. {
  4404. SystemAddress bindingAddress;
  4405. RakNetGUID guid;
  4406. RakNet::BitStream bsOut;
  4407. RakNet::BitStream bs((unsigned char*) data, length, false);
  4408. bs.IgnoreBytes(sizeof(MessageID));
  4409. bs.IgnoreBytes(sizeof(OFFLINE_MESSAGE_DATA_ID));
  4410. bool requiresSecurityOfThisClient=false;
  4411. #if LIBCAT_SECURITY==1
  4412. char remoteHandshakeChallenge[cat::EasyHandshake::CHALLENGE_BYTES];
  4413. if (rakPeer->_using_security)
  4414. {
  4415. char str1[64];
  4416. systemAddress.ToString(false, str1);
  4417. requiresSecurityOfThisClient=rakPeer->IsInSecurityExceptionList(str1)==false;
  4418. uint32_t cookie;
  4419. bs.Read(cookie);
  4420. CAT_AUDIT_PRINTF("AUDIT: Got cookie %i from %i:%i\n", cookie, systemAddress);
  4421. if (rakPeer->_cookie_jar->Verify(&systemAddress.address,sizeof(systemAddress.address), cookie)==false)
  4422. {
  4423. return true;
  4424. }
  4425. CAT_AUDIT_PRINTF("AUDIT: Cookie good!\n");
  4426. unsigned char clientWroteChallenge;
  4427. bs.Read(clientWroteChallenge);
  4428. if (requiresSecurityOfThisClient==true && clientWroteChallenge==0)
  4429. {
  4430. // Fail, client doesn't support security, and it is required
  4431. return true;
  4432. }
  4433. if (clientWroteChallenge)
  4434. {
  4435. bs.ReadAlignedBytes((unsigned char*) remoteHandshakeChallenge, cat::EasyHandshake::CHALLENGE_BYTES);
  4436. #ifdef CAT_AUDIT
  4437. printf("AUDIT: RECV CHALLENGE ");
  4438. for (int ii = 0; ii < sizeof(remoteHandshakeChallenge); ++ii)
  4439. {
  4440. printf("%02x", (cat::u8)remoteHandshakeChallenge[ii]);
  4441. }
  4442. printf("\n");
  4443. #endif
  4444. }
  4445. }
  4446. #endif // LIBCAT_SECURITY
  4447. bs.Read(bindingAddress);
  4448. uint16_t mtu;
  4449. bs.Read(mtu);
  4450. bs.Read(guid);
  4451. RakPeer::RemoteSystemStruct *rssFromSA = rakPeer->GetRemoteSystemFromSystemAddress( systemAddress, true, true );
  4452. bool IPAddrInUse = rssFromSA != 0 && rssFromSA->isActive;
  4453. RakPeer::RemoteSystemStruct *rssFromGuid = rakPeer->GetRemoteSystemFromGUID(guid, true);
  4454. bool GUIDInUse = rssFromGuid != 0 && rssFromGuid->isActive;
  4455. // IPAddrInUse, GuidInUse, outcome
  4456. // TRUE, , TRUE , ID_OPEN_CONNECTION_REPLY if they are the same, else ID_ALREADY_CONNECTED
  4457. // FALSE, , TRUE , ID_ALREADY_CONNECTED (someone else took this guid)
  4458. // TRUE, , FALSE , ID_ALREADY_CONNECTED (silently disconnected, restarted rakNet)
  4459. // FALSE , FALSE , Allow connection
  4460. int outcome;
  4461. if (IPAddrInUse & GUIDInUse)
  4462. {
  4463. if (rssFromSA==rssFromGuid && rssFromSA->connectMode==RakPeer::RemoteSystemStruct::UNVERIFIED_SENDER)
  4464. {
  4465. // ID_OPEN_CONNECTION_REPLY if they are the same
  4466. outcome=1;
  4467. // Note to self: If REQUESTED_CONNECTION, this means two systems attempted to connect to each other at the same time, and one finished first.
  4468. // Returns ID)_CONNECTION_REQUEST_ACCEPTED to one system, and ID_ALREADY_CONNECTED followed by ID_NEW_INCOMING_CONNECTION to another
  4469. }
  4470. else
  4471. {
  4472. // ID_ALREADY_CONNECTED (restarted raknet, connected again from same ip, plus someone else took this guid)
  4473. outcome=2;
  4474. }
  4475. }
  4476. else if (IPAddrInUse==false && GUIDInUse==true)
  4477. {
  4478. // ID_ALREADY_CONNECTED (someone else took this guid)
  4479. outcome=3;
  4480. }
  4481. else if (IPAddrInUse==true && GUIDInUse==false)
  4482. {
  4483. // ID_ALREADY_CONNECTED (silently disconnected, restarted rakNet)
  4484. outcome=4;
  4485. }
  4486. else
  4487. {
  4488. // Allow connection
  4489. outcome=0;
  4490. }
  4491. RakNet::BitStream bsAnswer;
  4492. bsAnswer.Write((MessageID)ID_OPEN_CONNECTION_REPLY_2);
  4493. bsAnswer.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  4494. bsAnswer.Write(rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
  4495. bsAnswer.Write(systemAddress);
  4496. bsAnswer.Write(mtu);
  4497. bsAnswer.Write(requiresSecurityOfThisClient);
  4498. if (outcome==1)
  4499. {
  4500. // Duplicate connection request packet from packetloss
  4501. // Send back the same answer
  4502. #if LIBCAT_SECURITY==1
  4503. if (requiresSecurityOfThisClient)
  4504. {
  4505. CAT_AUDIT_PRINTF("AUDIT: Resending public key and answer from packetloss. Sending ID_OPEN_CONNECTION_REPLY_2\n");
  4506. bsAnswer.WriteAlignedBytes((const unsigned char *) rssFromSA->answer,sizeof(rssFromSA->answer));
  4507. }
  4508. #endif // LIBCAT_SECURITY
  4509. unsigned int i;
  4510. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4511. rakPeer->pluginListNTS[i]->OnDirectSocketSend((const char*) bsAnswer.GetData(), bsAnswer.GetNumberOfBitsUsed(), systemAddress);
  4512. // SocketLayer::SendTo( rakNetSocket, (const char*) bsAnswer.GetData(), bsAnswer.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  4513. RNS2_SendParameters bsp;
  4514. bsp.data = (char*) bsAnswer.GetData();
  4515. bsp.length = bsAnswer.GetNumberOfBytesUsed();
  4516. bsp.systemAddress = systemAddress;
  4517. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  4518. return true;
  4519. }
  4520. else if (outcome!=0)
  4521. {
  4522. bsOut.Write((MessageID)ID_ALREADY_CONNECTED);
  4523. bsOut.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  4524. bsOut.Write(rakPeer->myGuid);
  4525. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4526. rakPeer->pluginListNTS[i]->OnDirectSocketSend((const char*) bsOut.GetData(), bsOut.GetNumberOfBitsUsed(), systemAddress);
  4527. // SocketLayer::SendTo( rakNetSocket, (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  4528. RNS2_SendParameters bsp;
  4529. bsp.data = (char*) bsOut.GetData();
  4530. bsp.length = bsOut.GetNumberOfBytesUsed();
  4531. bsp.systemAddress = systemAddress;
  4532. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  4533. return true;
  4534. }
  4535. if (rakPeer->AllowIncomingConnections()==false)
  4536. {
  4537. bsOut.Write((MessageID)ID_NO_FREE_INCOMING_CONNECTIONS);
  4538. bsOut.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  4539. bsOut.Write(rakPeer->myGuid);
  4540. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4541. rakPeer->pluginListNTS[i]->OnDirectSocketSend((const char*) bsOut.GetData(), bsOut.GetNumberOfBitsUsed(), systemAddress);
  4542. //SocketLayer::SendTo( rakNetSocket, (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  4543. RNS2_SendParameters bsp;
  4544. bsp.data = (char*) bsOut.GetData();
  4545. bsp.length = bsOut.GetNumberOfBytesUsed();
  4546. bsp.systemAddress = systemAddress;
  4547. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  4548. return true;
  4549. }
  4550. bool thisIPConnectedRecently=false;
  4551. rssFromSA = rakPeer->AssignSystemAddressToRemoteSystemList(systemAddress, RakPeer::RemoteSystemStruct::UNVERIFIED_SENDER, rakNetSocket, &thisIPConnectedRecently, bindingAddress, mtu, guid, requiresSecurityOfThisClient);
  4552. if (thisIPConnectedRecently==true)
  4553. {
  4554. bsOut.Write((MessageID)ID_IP_RECENTLY_CONNECTED);
  4555. bsOut.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  4556. bsOut.Write(rakPeer->myGuid);
  4557. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4558. rakPeer->pluginListNTS[i]->OnDirectSocketSend((const char*) bsOut.GetData(), bsOut.GetNumberOfBitsUsed(), systemAddress);
  4559. //SocketLayer::SendTo( rakNetSocket, (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  4560. RNS2_SendParameters bsp;
  4561. bsp.data = (char*) bsOut.GetData();
  4562. bsp.length = bsOut.GetNumberOfBytesUsed();
  4563. bsp.systemAddress = systemAddress;
  4564. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  4565. return true;
  4566. }
  4567. #if LIBCAT_SECURITY==1
  4568. if (requiresSecurityOfThisClient)
  4569. {
  4570. CAT_AUDIT_PRINTF("AUDIT: Writing public key. Sending ID_OPEN_CONNECTION_REPLY_2\n");
  4571. if (rakPeer->_server_handshake->ProcessChallenge(remoteHandshakeChallenge, rssFromSA->answer, rssFromSA->reliabilityLayer.GetAuthenticatedEncryption() ))
  4572. {
  4573. CAT_AUDIT_PRINTF("AUDIT: Challenge good!\n");
  4574. // Keep going to OK block
  4575. }
  4576. else
  4577. {
  4578. CAT_AUDIT_PRINTF("AUDIT: Challenge BAD!\n");
  4579. // Unassign this remote system
  4580. rakPeer->DereferenceRemoteSystem(systemAddress);
  4581. return true;
  4582. }
  4583. bsAnswer.WriteAlignedBytes((const unsigned char *) rssFromSA->answer,sizeof(rssFromSA->answer));
  4584. }
  4585. #endif // LIBCAT_SECURITY
  4586. unsigned int i;
  4587. for (i=0; i < rakPeer->pluginListNTS.Size(); i++)
  4588. rakPeer->pluginListNTS[i]->OnDirectSocketSend((const char*) bsAnswer.GetData(), bsAnswer.GetNumberOfBitsUsed(), systemAddress);
  4589. // SocketLayer::SendTo( rakNetSocket, (const char*) bsAnswer.GetData(), bsAnswer.GetNumberOfBytesUsed(), systemAddress, _FILE_AND_LINE_ );
  4590. RNS2_SendParameters bsp;
  4591. bsp.data = (char*) bsAnswer.GetData();
  4592. bsp.length = bsAnswer.GetNumberOfBytesUsed();
  4593. bsp.systemAddress = systemAddress;
  4594. rakNetSocket->Send(&bsp, _FILE_AND_LINE_);
  4595. }
  4596. return true;
  4597. }
  4598. return false;
  4599. }
  4600. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  4601. void ProcessNetworkPacket( SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, RakNet::TimeUS timeRead, BitStream &updateBitStream )
  4602. {
  4603. ProcessNetworkPacket(systemAddress,data,length,rakPeer,rakPeer->socketList[0],timeRead, updateBitStream);
  4604. }
  4605. void ProcessNetworkPacket( SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, RakNetSocket2* rakNetSocket, RakNet::TimeUS timeRead, BitStream &updateBitStream )
  4606. {
  4607. #if LIBCAT_SECURITY==1
  4608. #ifdef CAT_AUDIT
  4609. printf("AUDIT: RECV ");
  4610. for (int ii = 0; ii < length; ++ii)
  4611. {
  4612. printf("%02x", (cat::u8)data[ii]);
  4613. }
  4614. printf("\n");
  4615. #endif
  4616. #endif // LIBCAT_SECURITY
  4617. RakAssert(systemAddress.GetPort());
  4618. bool isOfflineMessage;
  4619. if (ProcessOfflineNetworkPacket(systemAddress, data, length, rakPeer, rakNetSocket, &isOfflineMessage, timeRead))
  4620. {
  4621. return;
  4622. }
  4623. // RakNet::Packet *packet;
  4624. RakPeer::RemoteSystemStruct *remoteSystem;
  4625. // See if this datagram came from a connected system
  4626. remoteSystem = rakPeer->GetRemoteSystemFromSystemAddress( systemAddress, true, true );
  4627. if ( remoteSystem )
  4628. {
  4629. // Handle regular incoming data
  4630. // HandleSocketReceiveFromConnectedPlayer is only safe to be called from the same thread as Update, which is this thread
  4631. if ( isOfflineMessage==false)
  4632. {
  4633. remoteSystem->reliabilityLayer.HandleSocketReceiveFromConnectedPlayer(
  4634. data, length, systemAddress, rakPeer->pluginListNTS, remoteSystem->MTUSize,
  4635. rakNetSocket, &rnr, timeRead, updateBitStream);
  4636. }
  4637. }
  4638. else
  4639. {
  4640. // int a=5;
  4641. // printf("--- Packet from unknown system %s\n", systemAddress.ToString());
  4642. }
  4643. }
  4644. }
  4645. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  4646. unsigned int RakPeer::GenerateSeedFromGuid(void)
  4647. {
  4648. /*
  4649. // Construct a random seed based on the initial guid value, and the last digits of the difference to each subsequent number
  4650. // This assumes that only the last 3 bits of each guidId integer has a meaningful amount of randomness between it and the prior number
  4651. unsigned int t = guid.g[0];
  4652. unsigned int i;
  4653. for (i=1; i < sizeof(guid.g) / sizeof(guid.g[0]); i++)
  4654. {
  4655. unsigned int diff = guid.g[i]-guid.g[i-1];
  4656. unsigned int diff3Bits = diff & 0x0007;
  4657. diff3Bits <<= 29;
  4658. diff3Bits >>= (i-1)*3;
  4659. t ^= diff3Bits;
  4660. }
  4661. return t;
  4662. */
  4663. return (unsigned int) ((myGuid.g >> 32) ^ myGuid.g);
  4664. }
  4665. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  4666. void RakPeer::DerefAllSockets(void)
  4667. {
  4668. unsigned int i;
  4669. for (i=0; i < socketList.Size(); i++)
  4670. {
  4671. delete socketList[i];
  4672. }
  4673. socketList.Clear(false, _FILE_AND_LINE_);
  4674. }
  4675. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  4676. unsigned int RakPeer::GetRakNetSocketFromUserConnectionSocketIndex(unsigned int userIndex) const
  4677. {
  4678. unsigned int i;
  4679. for (i=0; i < socketList.Size(); i++)
  4680. {
  4681. if (socketList[i]->GetUserConnectionSocketIndex()==userIndex)
  4682. return i;
  4683. }
  4684. RakAssert("GetRakNetSocketFromUserConnectionSocketIndex failed" && 0);
  4685. return (unsigned int) -1;
  4686. }
  4687. /*
  4688. // DS_APR
  4689. void RakPeer::ProcessChromePacket(RakNetSocket2 *s, const char *buffer, int dataSize, const SystemAddress& recvFromAddress, RakNet::TimeUS timeRead)
  4690. {
  4691. RakAssert(buffer);
  4692. RakAssert(dataSize > 0);
  4693. RakAssert(recvFromAddress.GetPort());
  4694. RNS2RecvStruct *recvFromStruct;
  4695. recvFromStruct=bufferedPackets.Allocate( _FILE_AND_LINE_ );
  4696. RakAssert(dataSize <= (int)sizeof(recvFromStruct->data));
  4697. memcpy(recvFromStruct->data, buffer, dataSize);
  4698. recvFromStruct->bytesRead=dataSize;
  4699. recvFromStruct->systemAddress=recvFromAddress;
  4700. recvFromStruct->timeRead=timeRead;
  4701. bufferedPackets.Push(recvFromStruct);
  4702. }
  4703. */
  4704. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  4705. /*
  4706. bool RakPeer::RunRecvFromOnce( RakNetSocket *s )
  4707. {
  4708. RakPeer::RecvFromStruct *recvFromStruct;
  4709. recvFromStruct=bufferedPackets.Allocate( _FILE_AND_LINE_ );
  4710. if (recvFromStruct != NULL)
  4711. {
  4712. recvFromStruct->s=s;
  4713. SocketLayer::RecvFromBlocking(s, this, recvFromStruct->data, &recvFromStruct->bytesRead, &recvFromStruct->systemAddress, &recvFromStruct->timeRead);
  4714. if (recvFromStruct->bytesRead>0)
  4715. {
  4716. RakAssert(recvFromStruct->systemAddress.GetPort());
  4717. bufferedPackets.Push(recvFromStruct);
  4718. quitAndDataEvents.SetEvent();
  4719. // Got data
  4720. return true;
  4721. }
  4722. else
  4723. {
  4724. bufferedPackets.Deallocate(recvFromStruct, _FILE_AND_LINE_);
  4725. }
  4726. }
  4727. // No data
  4728. return false;
  4729. }
  4730. */
  4731. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  4732. bool RakPeer::RunUpdateCycle(BitStream &updateBitStream )
  4733. {
  4734. RakPeer::RemoteSystemStruct * remoteSystem;
  4735. unsigned int activeSystemListIndex;
  4736. Packet *packet;
  4737. // int currentSentBytes,currentReceivedBytes;
  4738. // unsigned numberOfBytesUsed;
  4739. // BitSize_t numberOfBitsUsed;
  4740. //SystemAddress authoritativeClientSystemAddress;
  4741. BitSize_t bitSize;
  4742. unsigned int byteSize;
  4743. unsigned char *data;
  4744. SystemAddress systemAddress;
  4745. BufferedCommandStruct *bcs;
  4746. bool callerDataAllocationUsed;
  4747. RakNetStatistics *rnss;
  4748. RakNet::TimeUS timeNS=0;
  4749. RakNet::Time timeMS=0;
  4750. // This is here so RecvFromBlocking actually gets data from the same thread
  4751. #if defined(WINDOWS_STORE_RT)
  4752. #elif defined(_WIN32)
  4753. if (socketList[0]->GetSocketType()==RNS2T_WINDOWS && ((RNS2_Windows*)socketList[0])->GetSocketLayerOverride())
  4754. {
  4755. int len;
  4756. SystemAddress sender;
  4757. char dataOut[ MAXIMUM_MTU_SIZE ];
  4758. do {
  4759. len = ((RNS2_Windows*)socketList[0])->GetSocketLayerOverride()->RakNetRecvFrom(dataOut,&sender,true);
  4760. if (len>0)
  4761. ProcessNetworkPacket( sender, dataOut, len, this, socketList[0], RakNet::GetTimeUS(), updateBitStream );
  4762. } while (len>0);
  4763. }
  4764. #endif
  4765. // unsigned int socketListIndex;
  4766. RNS2RecvStruct *recvFromStruct;
  4767. while ((recvFromStruct=PopBufferedPacket())!=0)
  4768. {
  4769. /*
  4770. for (socketListIndex=0; socketListIndex < socketList.Size(); socketListIndex++)
  4771. {
  4772. if ((RakNetSocket*) socketList[socketListIndex]==recvFromStruct->s)
  4773. break;
  4774. }
  4775. if (socketListIndex!=socketList.Size())
  4776. */
  4777. ProcessNetworkPacket(recvFromStruct->systemAddress, recvFromStruct->data, recvFromStruct->bytesRead, this, recvFromStruct->socket, recvFromStruct->timeRead, updateBitStream);
  4778. DeallocRNS2RecvStruct(recvFromStruct, _FILE_AND_LINE_);
  4779. }
  4780. while ((bcs=bufferedCommands.PopInaccurate())!=0)
  4781. {
  4782. if (bcs->command==BufferedCommandStruct::BCS_SEND)
  4783. {
  4784. // GetTime is a very slow call so do it once and as late as possible
  4785. if (timeNS==0)
  4786. {
  4787. timeNS = RakNet::GetTimeUS();
  4788. timeMS = (RakNet::TimeMS)(timeNS/(RakNet::TimeUS)1000);
  4789. }
  4790. callerDataAllocationUsed=SendImmediate((char*)bcs->data, bcs->numberOfBitsToSend, bcs->priority, bcs->reliability, bcs->orderingChannel, bcs->systemIdentifier, bcs->broadcast, true, timeNS, bcs->receipt);
  4791. if ( callerDataAllocationUsed==false )
  4792. rakFree_Ex(bcs->data, _FILE_AND_LINE_ );
  4793. // Set the new connection state AFTER we call sendImmediate in case we are setting it to a disconnection state, which does not allow further sends
  4794. if (bcs->connectionMode!=RemoteSystemStruct::NO_ACTION )
  4795. {
  4796. remoteSystem=GetRemoteSystem( bcs->systemIdentifier, true, true );
  4797. if (remoteSystem)
  4798. remoteSystem->connectMode=bcs->connectionMode;
  4799. }
  4800. }
  4801. else if (bcs->command==BufferedCommandStruct::BCS_CLOSE_CONNECTION)
  4802. {
  4803. CloseConnectionInternal(bcs->systemIdentifier, false, true, bcs->orderingChannel, bcs->priority);
  4804. }
  4805. else if (bcs->command==BufferedCommandStruct::BCS_CHANGE_SYSTEM_ADDRESS)
  4806. {
  4807. // Reroute
  4808. RakPeer::RemoteSystemStruct *rssFromGuid = GetRemoteSystem(bcs->systemIdentifier.rakNetGuid,true,true);
  4809. if (rssFromGuid!=0)
  4810. {
  4811. unsigned int existingSystemIndex = GetRemoteSystemIndex(rssFromGuid->systemAddress);
  4812. ReferenceRemoteSystem(bcs->systemIdentifier.systemAddress, existingSystemIndex);
  4813. }
  4814. }
  4815. else if (bcs->command==BufferedCommandStruct::BCS_GET_SOCKET)
  4816. {
  4817. SocketQueryOutput *sqo;
  4818. if (bcs->systemIdentifier.IsUndefined())
  4819. {
  4820. sqo = socketQueryOutput.Allocate( _FILE_AND_LINE_ );
  4821. sqo->sockets=socketList;
  4822. socketQueryOutput.Push(sqo);
  4823. }
  4824. else
  4825. {
  4826. remoteSystem=GetRemoteSystem( bcs->systemIdentifier, true, true );
  4827. sqo = socketQueryOutput.Allocate( _FILE_AND_LINE_ );
  4828. sqo->sockets.Clear(false, _FILE_AND_LINE_);
  4829. if (remoteSystem)
  4830. {
  4831. sqo->sockets.Push(remoteSystem->rakNetSocket, _FILE_AND_LINE_ );
  4832. }
  4833. else
  4834. {
  4835. // Leave empty smart pointer
  4836. }
  4837. socketQueryOutput.Push(sqo);
  4838. }
  4839. }
  4840. #ifdef _DEBUG
  4841. bcs->data=0;
  4842. #endif
  4843. bufferedCommands.Deallocate(bcs, _FILE_AND_LINE_);
  4844. }
  4845. if (requestedConnectionQueue.IsEmpty()==false)
  4846. {
  4847. if (timeNS==0)
  4848. {
  4849. timeNS = RakNet::GetTimeUS();
  4850. timeMS = (RakNet::TimeMS)(timeNS/(RakNet::TimeUS)1000);
  4851. }
  4852. bool condition1, condition2;
  4853. unsigned requestedConnectionQueueIndex=0;
  4854. requestedConnectionQueueMutex.Lock();
  4855. while (requestedConnectionQueueIndex < requestedConnectionQueue.Size())
  4856. {
  4857. RequestedConnectionStruct *rcs;
  4858. rcs = requestedConnectionQueue[requestedConnectionQueueIndex];
  4859. requestedConnectionQueueMutex.Unlock();
  4860. if (rcs->nextRequestTime < timeMS)
  4861. {
  4862. condition1=rcs->requestsMade==rcs->sendConnectionAttemptCount+1;
  4863. condition2=(bool)((rcs->systemAddress==UNASSIGNED_SYSTEM_ADDRESS)==1);
  4864. // If too many requests made or a hole then remove this if possible, otherwise invalidate it
  4865. if (condition1 || condition2)
  4866. {
  4867. if (rcs->data)
  4868. {
  4869. rakFree_Ex(rcs->data, _FILE_AND_LINE_ );
  4870. rcs->data=0;
  4871. }
  4872. if (condition1 && !condition2 && rcs->actionToTake==RequestedConnectionStruct::CONNECT)
  4873. {
  4874. // Tell user of connection attempt failed
  4875. packet=AllocPacket(sizeof( char ), _FILE_AND_LINE_);
  4876. packet->data[ 0 ] = ID_CONNECTION_ATTEMPT_FAILED; // Attempted a connection and couldn't
  4877. packet->bitSize = ( sizeof( char ) * 8);
  4878. packet->systemAddress = rcs->systemAddress;
  4879. AddPacketToProducer(packet);
  4880. }
  4881. #if LIBCAT_SECURITY==1
  4882. CAT_AUDIT_PRINTF("AUDIT: Connection attempt FAILED so deleting rcs->client_handshake object %x\n", rcs->client_handshake);
  4883. RakNet::OP_DELETE(rcs->client_handshake,_FILE_AND_LINE_);
  4884. #endif
  4885. RakNet::OP_DELETE(rcs,_FILE_AND_LINE_);
  4886. requestedConnectionQueueMutex.Lock();
  4887. for (unsigned int k=0; k < requestedConnectionQueue.Size(); k++)
  4888. {
  4889. if (requestedConnectionQueue[k]==rcs)
  4890. {
  4891. requestedConnectionQueue.RemoveAtIndex(k);
  4892. break;
  4893. }
  4894. }
  4895. requestedConnectionQueueMutex.Unlock();
  4896. }
  4897. else
  4898. {
  4899. int MTUSizeIndex = rcs->requestsMade / (rcs->sendConnectionAttemptCount/NUM_MTU_SIZES);
  4900. if (MTUSizeIndex>=NUM_MTU_SIZES)
  4901. MTUSizeIndex=NUM_MTU_SIZES-1;
  4902. rcs->requestsMade++;
  4903. rcs->nextRequestTime=timeMS+rcs->timeBetweenSendConnectionAttemptsMS;
  4904. RakNet::BitStream bitStream;
  4905. //WriteOutOfBandHeader(&bitStream, ID_USER_PACKET_ENUM);
  4906. bitStream.Write((MessageID)ID_OPEN_CONNECTION_REQUEST_1);
  4907. bitStream.WriteAlignedBytes((const unsigned char*) OFFLINE_MESSAGE_DATA_ID, sizeof(OFFLINE_MESSAGE_DATA_ID));
  4908. bitStream.Write((MessageID)RAKNET_PROTOCOL_VERSION);
  4909. bitStream.PadWithZeroToByteLength(mtuSizes[MTUSizeIndex]-UDP_HEADER_SIZE);
  4910. char str[256];
  4911. rcs->systemAddress.ToString(true,str);
  4912. //RAKNET_DEBUG_PRINTF("%i:IOCR, ", __LINE__);
  4913. unsigned i;
  4914. for (i=0; i < pluginListNTS.Size(); i++)
  4915. pluginListNTS[i]->OnDirectSocketSend((const char*) bitStream.GetData(), bitStream.GetNumberOfBitsUsed(), rcs->systemAddress);
  4916. RakNetSocket2 *socketToUse;
  4917. if (rcs->socket == 0)
  4918. socketToUse = socketList[rcs->socketIndex];
  4919. else
  4920. socketToUse = rcs->socket;
  4921. rcs->systemAddress.FixForIPVersion(socketToUse->GetBoundAddress());
  4922. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  4923. if (socketToUse->IsBerkleySocket())
  4924. ((RNS2_Berkley*)socketToUse)->SetDoNotFragment(1);
  4925. #endif
  4926. // SocketLayer::SetDoNotFragment(socketToUse, 1);
  4927. RakNet::Time sendToStart=RakNet::GetTime();
  4928. RNS2_SendParameters bsp;
  4929. bsp.data = (char*) bitStream.GetData();
  4930. bsp.length = bitStream.GetNumberOfBytesUsed();
  4931. bsp.systemAddress = rcs->systemAddress;
  4932. if (socketToUse->Send(&bsp, _FILE_AND_LINE_) == 10040)
  4933. // if (SocketLayer::SendTo( socketToUse, (const char*) bitStream.GetData(), bitStream.GetNumberOfBytesUsed(), rcs->systemAddress, _FILE_AND_LINE_ )==-10040)
  4934. {
  4935. // Don't use this MTU size again
  4936. rcs->requestsMade = (unsigned char) ((MTUSizeIndex + 1) * (rcs->sendConnectionAttemptCount/NUM_MTU_SIZES));
  4937. rcs->nextRequestTime=timeMS;
  4938. }
  4939. else
  4940. {
  4941. RakNet::Time sendToEnd=RakNet::GetTime();
  4942. if (sendToEnd-sendToStart>100)
  4943. {
  4944. // Drop to lowest MTU
  4945. int lowestMtuIndex = rcs->sendConnectionAttemptCount/NUM_MTU_SIZES * (NUM_MTU_SIZES - 1);
  4946. if (lowestMtuIndex > rcs->requestsMade)
  4947. {
  4948. rcs->requestsMade = (unsigned char) lowestMtuIndex;
  4949. rcs->nextRequestTime=timeMS;
  4950. }
  4951. else
  4952. rcs->requestsMade=(unsigned char)(rcs->sendConnectionAttemptCount+1);
  4953. }
  4954. }
  4955. // SocketLayer::SetDoNotFragment(socketToUse, 0);
  4956. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  4957. if (socketToUse->IsBerkleySocket())
  4958. ((RNS2_Berkley*)socketToUse)->SetDoNotFragment(0);
  4959. #endif
  4960. requestedConnectionQueueIndex++;
  4961. }
  4962. }
  4963. else
  4964. requestedConnectionQueueIndex++;
  4965. requestedConnectionQueueMutex.Lock();
  4966. }
  4967. requestedConnectionQueueMutex.Unlock();
  4968. }
  4969. // remoteSystemList in network thread
  4970. for ( activeSystemListIndex = 0; activeSystemListIndex < activeSystemListSize; ++activeSystemListIndex )
  4971. //for ( remoteSystemIndex = 0; remoteSystemIndex < remoteSystemListSize; ++remoteSystemIndex )
  4972. {
  4973. // I'm using systemAddress from remoteSystemList but am not locking it because this loop is called very frequently and it doesn't
  4974. // matter if we miss or do an extra update. The reliability layers themselves never care which player they are associated with
  4975. //systemAddress = remoteSystemList[ remoteSystemIndex ].systemAddress;
  4976. // Allow the systemAddress for this remote system list to change. We don't care if it changes now.
  4977. // remoteSystemList[ remoteSystemIndex ].allowSystemAddressAssigment=true;
  4978. // Found an active remote system
  4979. remoteSystem = activeSystemList[ activeSystemListIndex ];
  4980. systemAddress = remoteSystem->systemAddress;
  4981. RakAssert(systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
  4982. // Update is only safe to call from the same thread that calls HandleSocketReceiveFromConnectedPlayer,
  4983. // which is this thread
  4984. if (timeNS==0)
  4985. {
  4986. timeNS = RakNet::GetTimeUS();
  4987. timeMS = (RakNet::TimeMS)(timeNS/(RakNet::TimeUS)1000);
  4988. //RAKNET_DEBUG_PRINTF("timeNS = %I64i timeMS=%i\n", timeNS, timeMS);
  4989. }
  4990. if (timeMS > remoteSystem->lastReliableSend && timeMS-remoteSystem->lastReliableSend > remoteSystem->reliabilityLayer.GetTimeoutTime()/2 && remoteSystem->connectMode==RemoteSystemStruct::CONNECTED)
  4991. {
  4992. // If no reliable packets are waiting for an ack, do a one byte reliable send so that disconnections are noticed
  4993. RakNetStatistics rakNetStatistics;
  4994. rnss=remoteSystem->reliabilityLayer.GetStatistics(&rakNetStatistics);
  4995. if (rnss->messagesInResendBuffer==0)
  4996. {
  4997. PingInternal( systemAddress, true, RELIABLE );
  4998. //remoteSystem->lastReliableSend=timeMS+remoteSystem->reliabilityLayer.GetTimeoutTime();
  4999. remoteSystem->lastReliableSend=timeMS;
  5000. }
  5001. }
  5002. remoteSystem->reliabilityLayer.Update( remoteSystem->rakNetSocket, systemAddress, remoteSystem->MTUSize, timeNS, maxOutgoingBPS, pluginListNTS, &rnr, updateBitStream ); // systemAddress only used for the internet simulator test
  5003. // Check for failure conditions
  5004. if ( remoteSystem->reliabilityLayer.IsDeadConnection() ||
  5005. ((remoteSystem->connectMode==RemoteSystemStruct::DISCONNECT_ASAP || remoteSystem->connectMode==RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY) && remoteSystem->reliabilityLayer.IsOutgoingDataWaiting()==false) ||
  5006. (remoteSystem->connectMode==RemoteSystemStruct::DISCONNECT_ON_NO_ACK && (remoteSystem->reliabilityLayer.AreAcksWaiting()==false || remoteSystem->reliabilityLayer.AckTimeout(timeMS)==true)) ||
  5007. ((
  5008. (remoteSystem->connectMode==RemoteSystemStruct::REQUESTED_CONNECTION ||
  5009. remoteSystem->connectMode==RemoteSystemStruct::HANDLING_CONNECTION_REQUEST ||
  5010. remoteSystem->connectMode==RemoteSystemStruct::UNVERIFIED_SENDER)
  5011. && timeMS > remoteSystem->connectionTime && timeMS - remoteSystem->connectionTime > 10000))
  5012. )
  5013. {
  5014. // RAKNET_DEBUG_PRINTF("timeMS=%i remoteSystem->connectionTime=%i\n", timeMS, remoteSystem->connectionTime );
  5015. // Failed. Inform the user?
  5016. // TODO - RakNet 4.0 - Return a different message identifier for DISCONNECT_ASAP_SILENTLY and DISCONNECT_ASAP than for DISCONNECT_ON_NO_ACK
  5017. // The first two mean we called CloseConnection(), the last means the other system sent us ID_DISCONNECTION_NOTIFICATION
  5018. if (remoteSystem->connectMode==RemoteSystemStruct::CONNECTED || remoteSystem->connectMode==RemoteSystemStruct::REQUESTED_CONNECTION
  5019. || remoteSystem->connectMode==RemoteSystemStruct::DISCONNECT_ASAP || remoteSystem->connectMode==RemoteSystemStruct::DISCONNECT_ON_NO_ACK)
  5020. {
  5021. // RakNet::BitStream undeliveredMessages;
  5022. // remoteSystem->reliabilityLayer.GetUndeliveredMessages(&undeliveredMessages,remoteSystem->MTUSize);
  5023. // packet=AllocPacket(sizeof( char ) + undeliveredMessages.GetNumberOfBytesUsed());
  5024. packet=AllocPacket(sizeof( char ), _FILE_AND_LINE_);
  5025. if (remoteSystem->connectMode==RemoteSystemStruct::REQUESTED_CONNECTION)
  5026. packet->data[ 0 ] = ID_CONNECTION_ATTEMPT_FAILED; // Attempted a connection and couldn't
  5027. else if (remoteSystem->connectMode==RemoteSystemStruct::CONNECTED)
  5028. packet->data[ 0 ] = ID_CONNECTION_LOST; // DeadConnection
  5029. else
  5030. packet->data[ 0 ] = ID_DISCONNECTION_NOTIFICATION; // DeadConnection
  5031. // memcpy(packet->data+1, undeliveredMessages.GetData(), undeliveredMessages.GetNumberOfBytesUsed());
  5032. packet->guid = remoteSystem->guid;
  5033. packet->systemAddress = systemAddress;
  5034. packet->systemAddress.systemIndex = remoteSystem->remoteSystemIndex;
  5035. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  5036. AddPacketToProducer(packet);
  5037. }
  5038. // else connection shutting down, don't bother telling the user
  5039. #ifdef _DO_PRINTF
  5040. RAKNET_DEBUG_PRINTF("Connection dropped for player %i:%i\n", systemAddress);
  5041. #endif
  5042. CloseConnectionInternal( systemAddress, false, true, 0, LOW_PRIORITY );
  5043. continue;
  5044. }
  5045. // Ping this guy if it is time to do so
  5046. if ( remoteSystem->connectMode==RemoteSystemStruct::CONNECTED && timeMS > remoteSystem->nextPingTime && ( occasionalPing || remoteSystem->lowestPing == (unsigned short)-1 ) )
  5047. {
  5048. remoteSystem->nextPingTime = timeMS + 5000;
  5049. PingInternal( systemAddress, true, UNRELIABLE );
  5050. // Update again immediately after this tick so the ping goes out right away
  5051. quitAndDataEvents.SetEvent();
  5052. }
  5053. // Find whoever has the lowest player ID
  5054. //if (systemAddress < authoritativeClientSystemAddress)
  5055. // authoritativeClientSystemAddress=systemAddress;
  5056. // Does the reliability layer have any packets waiting for us?
  5057. // To be thread safe, this has to be called in the same thread as HandleSocketReceiveFromConnectedPlayer
  5058. bitSize = remoteSystem->reliabilityLayer.Receive( &data );
  5059. while ( bitSize > 0 )
  5060. {
  5061. // These types are for internal use and should never arrive from a network packet
  5062. if (data[0]==ID_CONNECTION_ATTEMPT_FAILED)
  5063. {
  5064. RakAssert(0);
  5065. bitSize=0;
  5066. continue;
  5067. }
  5068. // Fast and easy - just use the data that was returned
  5069. byteSize = (unsigned int) BITS_TO_BYTES( bitSize );
  5070. // For unknown senders we only accept a few specific packets
  5071. if (remoteSystem->connectMode==RemoteSystemStruct::UNVERIFIED_SENDER)
  5072. {
  5073. if ( (unsigned char)(data)[0] == ID_CONNECTION_REQUEST )
  5074. {
  5075. ParseConnectionRequestPacket(remoteSystem, systemAddress, (const char*)data, byteSize);
  5076. rakFree_Ex(data, _FILE_AND_LINE_ );
  5077. }
  5078. else
  5079. {
  5080. CloseConnectionInternal( systemAddress, false, true, 0, LOW_PRIORITY );
  5081. #ifdef _DO_PRINTF
  5082. RAKNET_DEBUG_PRINTF("Temporarily banning %i:%i for sending nonsense data\n", systemAddress);
  5083. #endif
  5084. char str1[64];
  5085. systemAddress.ToString(false, str1);
  5086. AddToBanList(str1, remoteSystem->reliabilityLayer.GetTimeoutTime());
  5087. rakFree_Ex(data, _FILE_AND_LINE_ );
  5088. }
  5089. }
  5090. else
  5091. {
  5092. // However, if we are connected we still take a connection request in case both systems are trying to connect to each other
  5093. // at the same time
  5094. if ( (unsigned char)(data)[0] == ID_CONNECTION_REQUEST )
  5095. {
  5096. // 04/27/06 This is wrong. With cross connections, we can both have initiated the connection are in state REQUESTED_CONNECTION
  5097. // 04/28/06 Downgrading connections from connected will close the connection due to security at ((remoteSystem->connectMode!=RemoteSystemStruct::CONNECTED && time > remoteSystem->connectionTime && time - remoteSystem->connectionTime > 10000))
  5098. if (remoteSystem->connectMode==RemoteSystemStruct::REQUESTED_CONNECTION)
  5099. {
  5100. ParseConnectionRequestPacket(remoteSystem, systemAddress, (const char*)data, byteSize);
  5101. }
  5102. else
  5103. {
  5104. RakNet::BitStream bs((unsigned char*) data,byteSize,false);
  5105. bs.IgnoreBytes(sizeof(MessageID));
  5106. bs.IgnoreBytes(sizeof(OFFLINE_MESSAGE_DATA_ID));
  5107. bs.IgnoreBytes(RakNetGUID::size());
  5108. RakNet::Time incomingTimestamp;
  5109. bs.Read(incomingTimestamp);
  5110. // Got a connection request message from someone we are already connected to. Just reply normally.
  5111. // This can happen due to race conditions with the fully connected mesh
  5112. OnConnectionRequest( remoteSystem, incomingTimestamp );
  5113. }
  5114. rakFree_Ex(data, _FILE_AND_LINE_ );
  5115. }
  5116. else if ( (unsigned char) data[ 0 ] == ID_NEW_INCOMING_CONNECTION && byteSize > sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned short)+sizeof(RakNet::Time)*2 )
  5117. {
  5118. if (remoteSystem->connectMode==RemoteSystemStruct::HANDLING_CONNECTION_REQUEST)
  5119. {
  5120. remoteSystem->connectMode=RemoteSystemStruct::CONNECTED;
  5121. PingInternal( systemAddress, true, UNRELIABLE );
  5122. // Update again immediately after this tick so the ping goes out right away
  5123. quitAndDataEvents.SetEvent();
  5124. RakNet::BitStream inBitStream((unsigned char *) data, byteSize, false);
  5125. SystemAddress bsSystemAddress;
  5126. inBitStream.IgnoreBits(8);
  5127. inBitStream.Read(bsSystemAddress);
  5128. for (unsigned int i=0; i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++)
  5129. inBitStream.Read(remoteSystem->theirInternalSystemAddress[i]);
  5130. RakNet::Time sendPingTime, sendPongTime;
  5131. inBitStream.Read(sendPingTime);
  5132. inBitStream.Read(sendPongTime);
  5133. OnConnectedPong(sendPingTime,sendPongTime,remoteSystem);
  5134. // Overwrite the data in the packet
  5135. // NewIncomingConnectionStruct newIncomingConnectionStruct;
  5136. // RakNet::BitStream nICS_BS( data, NewIncomingConnectionStruct_Size, false );
  5137. // newIncomingConnectionStruct.Deserialize( nICS_BS );
  5138. remoteSystem->myExternalSystemAddress = bsSystemAddress;
  5139. // Bug: If A connects to B through R, A's firstExternalID is set to R. If A tries to send to R, sends to loopback because R==firstExternalID
  5140. // Correct fix is to specify in Connect() if target is through a proxy.
  5141. // However, in practice you have to connect to something else first anyway to know about the proxy. So setting once only is good enough
  5142. if (firstExternalID==UNASSIGNED_SYSTEM_ADDRESS)
  5143. {
  5144. firstExternalID=bsSystemAddress;
  5145. firstExternalID.debugPort=ntohs(firstExternalID.address.addr4.sin_port);
  5146. }
  5147. // Send this info down to the game
  5148. packet=AllocPacket(byteSize, data, _FILE_AND_LINE_);
  5149. packet->bitSize = bitSize;
  5150. packet->systemAddress = systemAddress;
  5151. packet->systemAddress.systemIndex = remoteSystem->remoteSystemIndex;
  5152. packet->guid = remoteSystem->guid;
  5153. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  5154. AddPacketToProducer(packet);
  5155. }
  5156. else
  5157. {
  5158. // Send to game even if already connected. This could happen when connecting to 127.0.0.1
  5159. // Ignore, already connected
  5160. // rakFree_Ex(data, _FILE_AND_LINE_ );
  5161. }
  5162. }
  5163. else if ( (unsigned char) data[ 0 ] == ID_CONNECTED_PONG && byteSize == sizeof(unsigned char)+sizeof(RakNet::Time)*2 )
  5164. {
  5165. RakNet::Time sendPingTime, sendPongTime;
  5166. // Copy into the ping times array the current time - the value returned
  5167. // First extract the sent ping
  5168. RakNet::BitStream inBitStream( (unsigned char *) data, byteSize, false );
  5169. //PingStruct ps;
  5170. //ps.Deserialize(psBS);
  5171. inBitStream.IgnoreBits(8);
  5172. inBitStream.Read(sendPingTime);
  5173. inBitStream.Read(sendPongTime);
  5174. OnConnectedPong(sendPingTime,sendPongTime,remoteSystem);
  5175. rakFree_Ex(data, _FILE_AND_LINE_ );
  5176. }
  5177. else if ( (unsigned char)data[0] == ID_CONNECTED_PING && byteSize == sizeof(unsigned char)+sizeof(RakNet::Time) )
  5178. {
  5179. RakNet::BitStream inBitStream( (unsigned char *) data, byteSize, false );
  5180. inBitStream.IgnoreBits(8);
  5181. RakNet::Time sendPingTime;
  5182. inBitStream.Read(sendPingTime);
  5183. RakNet::BitStream outBitStream;
  5184. outBitStream.Write((MessageID)ID_CONNECTED_PONG);
  5185. outBitStream.Write(sendPingTime);
  5186. outBitStream.Write(RakNet::GetTime());
  5187. SendImmediate( (char*)outBitStream.GetData(), outBitStream.GetNumberOfBitsUsed(), IMMEDIATE_PRIORITY, UNRELIABLE, 0, systemAddress, false, false, RakNet::GetTimeUS(), 0 );
  5188. // Update again immediately after this tick so the ping goes out right away
  5189. quitAndDataEvents.SetEvent();
  5190. rakFree_Ex(data, _FILE_AND_LINE_ );
  5191. }
  5192. else if ( (unsigned char) data[ 0 ] == ID_DISCONNECTION_NOTIFICATION )
  5193. {
  5194. // We shouldn't close the connection immediately because we need to ack the ID_DISCONNECTION_NOTIFICATION
  5195. remoteSystem->connectMode=RemoteSystemStruct::DISCONNECT_ON_NO_ACK;
  5196. rakFree_Ex(data, _FILE_AND_LINE_ );
  5197. // AddPacketToProducer(packet);
  5198. }
  5199. else if ( (unsigned char)(data)[0] == ID_DETECT_LOST_CONNECTIONS && byteSize == sizeof(unsigned char) )
  5200. {
  5201. // Do nothing
  5202. rakFree_Ex(data, _FILE_AND_LINE_ );
  5203. }
  5204. else if ( (unsigned char)(data)[0] == ID_INVALID_PASSWORD )
  5205. {
  5206. if (remoteSystem->connectMode==RemoteSystemStruct::REQUESTED_CONNECTION)
  5207. {
  5208. packet=AllocPacket(byteSize, data, _FILE_AND_LINE_);
  5209. packet->bitSize = bitSize;
  5210. packet->systemAddress = systemAddress;
  5211. packet->systemAddress.systemIndex = remoteSystem->remoteSystemIndex;
  5212. packet->guid = remoteSystem->guid;
  5213. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  5214. AddPacketToProducer(packet);
  5215. remoteSystem->connectMode=RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY;
  5216. }
  5217. else
  5218. {
  5219. rakFree_Ex(data, _FILE_AND_LINE_ );
  5220. }
  5221. }
  5222. else if ( (unsigned char)(data)[0] == ID_CONNECTION_REQUEST_ACCEPTED )
  5223. {
  5224. if (byteSize > sizeof(MessageID)+sizeof(unsigned int)+sizeof(unsigned short)+sizeof(SystemIndex)+sizeof(RakNet::Time)*2)
  5225. {
  5226. // Make sure this connection accept is from someone we wanted to connect to
  5227. bool allowConnection, alreadyConnected;
  5228. if (remoteSystem->connectMode==RemoteSystemStruct::HANDLING_CONNECTION_REQUEST ||
  5229. remoteSystem->connectMode==RemoteSystemStruct::REQUESTED_CONNECTION ||
  5230. allowConnectionResponseIPMigration)
  5231. allowConnection=true;
  5232. else
  5233. allowConnection=false;
  5234. if (remoteSystem->connectMode==RemoteSystemStruct::HANDLING_CONNECTION_REQUEST)
  5235. alreadyConnected=true;
  5236. else
  5237. alreadyConnected=false;
  5238. if ( allowConnection )
  5239. {
  5240. SystemAddress externalID;
  5241. SystemIndex systemIndex;
  5242. // SystemAddress internalID;
  5243. RakNet::BitStream inBitStream((unsigned char *) data, byteSize, false);
  5244. inBitStream.IgnoreBits(8);
  5245. // inBitStream.Read(remotePort);
  5246. inBitStream.Read(externalID);
  5247. inBitStream.Read(systemIndex);
  5248. for (unsigned int i=0; i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++)
  5249. inBitStream.Read(remoteSystem->theirInternalSystemAddress[i]);
  5250. RakNet::Time sendPingTime, sendPongTime;
  5251. inBitStream.Read(sendPingTime);
  5252. inBitStream.Read(sendPongTime);
  5253. OnConnectedPong(sendPingTime, sendPongTime, remoteSystem);
  5254. // Find a free remote system struct to use
  5255. // RakNet::BitStream casBitS(data, byteSize, false);
  5256. // ConnectionAcceptStruct cas;
  5257. // cas.Deserialize(casBitS);
  5258. // systemAddress.GetPort() = remotePort;
  5259. // The remote system told us our external IP, so save it
  5260. remoteSystem->myExternalSystemAddress = externalID;
  5261. remoteSystem->connectMode=RemoteSystemStruct::CONNECTED;
  5262. // Bug: If A connects to B through R, A's firstExternalID is set to R. If A tries to send to R, sends to loopback because R==firstExternalID
  5263. // Correct fix is to specify in Connect() if target is through a proxy.
  5264. // However, in practice you have to connect to something else first anyway to know about the proxy. So setting once only is good enough
  5265. if (firstExternalID==UNASSIGNED_SYSTEM_ADDRESS)
  5266. {
  5267. firstExternalID=externalID;
  5268. firstExternalID.debugPort=ntohs(firstExternalID.address.addr4.sin_port);
  5269. }
  5270. // Send the connection request complete to the game
  5271. packet=AllocPacket(byteSize, data, _FILE_AND_LINE_);
  5272. packet->bitSize = byteSize * 8;
  5273. packet->systemAddress = systemAddress;
  5274. packet->systemAddress.systemIndex = ( SystemIndex ) GetIndexFromSystemAddress( systemAddress, true );
  5275. packet->guid = remoteSystem->guid;
  5276. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  5277. AddPacketToProducer(packet);
  5278. RakNet::BitStream outBitStream;
  5279. outBitStream.Write((MessageID)ID_NEW_INCOMING_CONNECTION);
  5280. outBitStream.Write(systemAddress);
  5281. for (unsigned int i=0; i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++)
  5282. outBitStream.Write(ipList[i]);
  5283. outBitStream.Write(sendPongTime);
  5284. outBitStream.Write(RakNet::GetTime());
  5285. SendImmediate( (char*)outBitStream.GetData(), outBitStream.GetNumberOfBitsUsed(), IMMEDIATE_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false, false, RakNet::GetTimeUS(), 0 );
  5286. if (alreadyConnected==false)
  5287. {
  5288. PingInternal( systemAddress, true, UNRELIABLE );
  5289. }
  5290. }
  5291. else
  5292. {
  5293. // Ignore, already connected
  5294. rakFree_Ex(data, _FILE_AND_LINE_ );
  5295. }
  5296. }
  5297. else
  5298. {
  5299. // Version mismatch error?
  5300. RakAssert(0);
  5301. rakFree_Ex(data, _FILE_AND_LINE_ );
  5302. }
  5303. }
  5304. else
  5305. {
  5306. // What do I do if I get a message from a system, before I am fully connected?
  5307. // I can either ignore it or give it to the user
  5308. // It seems like giving it to the user is a better option
  5309. if ((data[0]>=(MessageID)ID_TIMESTAMP || data[0]==ID_SND_RECEIPT_ACKED || data[0]==ID_SND_RECEIPT_LOSS) &&
  5310. remoteSystem->isActive
  5311. )
  5312. {
  5313. packet=AllocPacket(byteSize, data, _FILE_AND_LINE_);
  5314. packet->bitSize = bitSize;
  5315. packet->systemAddress = systemAddress;
  5316. packet->systemAddress.systemIndex = remoteSystem->remoteSystemIndex;
  5317. packet->guid = remoteSystem->guid;
  5318. packet->guid.systemIndex=packet->systemAddress.systemIndex;
  5319. AddPacketToProducer(packet);
  5320. }
  5321. else
  5322. {
  5323. rakFree_Ex(data, _FILE_AND_LINE_ );
  5324. }
  5325. }
  5326. }
  5327. // Does the reliability layer have any more packets waiting for us?
  5328. // To be thread safe, this has to be called in the same thread as HandleSocketReceiveFromConnectedPlayer
  5329. bitSize = remoteSystem->reliabilityLayer.Receive( &data );
  5330. }
  5331. }
  5332. return true;
  5333. }
  5334. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  5335. void RakPeer::OnRNS2Recv(RNS2RecvStruct *recvStruct)
  5336. {
  5337. if (incomingDatagramEventHandler)
  5338. {
  5339. if (incomingDatagramEventHandler(recvStruct)!=true)
  5340. return;
  5341. }
  5342. PushBufferedPacket(recvStruct);
  5343. quitAndDataEvents.SetEvent();
  5344. }
  5345. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  5346. /*
  5347. RAK_THREAD_DECLARATION(RakNet::RecvFromLoop)
  5348. {
  5349. #if defined(SN_TARGET_PSP2)
  5350. RakPeerAndIndex *rpai = ( RakPeerAndIndex * ) RakThread::GetRealThreadArgument(callGetRealThreadArgument);
  5351. #else
  5352. RakPeerAndIndex *rpai = ( RakPeerAndIndex * ) arguments;
  5353. #endif
  5354. RakPeer * rakPeer = rpai->rakPeer;
  5355. RakNetSocket *s = rpai->s;
  5356. RakNet::OP_DELETE(rpai,_FILE_AND_LINE_);
  5357. rakPeer->isRecvFromLoopThreadActive.Increment();
  5358. while ( rakPeer->endThreads == false )
  5359. {
  5360. if (rakPeer->RunRecvFromOnce(s)==false &&
  5361. s->GetBlockingSocket()==false)
  5362. RakSleep(0);
  5363. }
  5364. rakPeer->isRecvFromLoopThreadActive.Decrement();
  5365. #if defined(SN_TARGET_PSP2)
  5366. return sceKernelExitDeleteThread(0);
  5367. #else
  5368. return 0;
  5369. #endif
  5370. }
  5371. */
  5372. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  5373. RAK_THREAD_DECLARATION(RakNet::UpdateNetworkLoop)
  5374. {
  5375. RakPeer * rakPeer = ( RakPeer * ) arguments;
  5376. /*
  5377. // 11/15/05 - this is slower than Sleep()
  5378. #ifdef _WIN32
  5379. #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
  5380. // Lets see if these timers give better performance than Sleep
  5381. HANDLE timerHandle;
  5382. LARGE_INTEGER dueTime;
  5383. if ( rakPeer->threadSleepTimer <= 0 )
  5384. rakPeer->threadSleepTimer = 1;
  5385. // 2nd parameter of false means synchronization timer instead of manual-reset timer
  5386. timerHandle = CreateWaitableTimer( NULL, FALSE, 0 );
  5387. RakAssert( timerHandle );
  5388. dueTime.QuadPart = -10000 * rakPeer->threadSleepTimer; // 10000 is 1 ms?
  5389. BOOL success = SetWaitableTimer( timerHandle, &dueTime, rakPeer->threadSleepTimer, NULL, NULL, FALSE );
  5390. (void) success;
  5391. RakAssert( success );
  5392. #endif
  5393. #endif
  5394. */
  5395. BitStream updateBitStream( MAXIMUM_MTU_SIZE
  5396. #if LIBCAT_SECURITY==1
  5397. + cat::AuthenticatedEncryption::OVERHEAD_BYTES
  5398. #endif
  5399. );
  5400. //
  5401. rakPeer->isMainLoopThreadActive = true;
  5402. while ( rakPeer->endThreads == false )
  5403. {
  5404. // #ifdef _DEBUG
  5405. // // Sanity check, make sure RunUpdateCycle does not block or not otherwise get called for a long time
  5406. // RakNetTime thisCall=RakNet::GetTime();
  5407. // RakAssert(thisCall-lastCall<250);
  5408. // lastCall=thisCall;
  5409. // #endif
  5410. if (rakPeer->userUpdateThreadPtr)
  5411. rakPeer->userUpdateThreadPtr(rakPeer, rakPeer->userUpdateThreadData);
  5412. rakPeer->RunUpdateCycle(updateBitStream);
  5413. // Pending sends go out this often, unless quitAndDataEvents is set
  5414. rakPeer->quitAndDataEvents.WaitOnEvent(10);
  5415. /*
  5416. // #if ((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) &&
  5417. #if defined(USE_WAIT_FOR_MULTIPLE_EVENTS) && defined(_WIN32)
  5418. if (rakPeer->threadSleepTimer>0)
  5419. {
  5420. WSAEVENT eventArray[256];
  5421. unsigned int i, eventArrayIndex;
  5422. for (i=0,eventArrayIndex=0; i < rakPeer->socketList.Size(); i++)
  5423. {
  5424. if (rakPeer->socketList[i]->recvEvent!=INVALID_HANDLE_VALUE)
  5425. {
  5426. eventArray[eventArrayIndex]=rakPeer->socketList[i]->recvEvent;
  5427. eventArrayIndex++;
  5428. if (eventArrayIndex==256)
  5429. break;
  5430. }
  5431. }
  5432. WSAWaitForMultipleEvents(eventArrayIndex,(const HANDLE*) &eventArray,FALSE,rakPeer->threadSleepTimer,FALSE);
  5433. }
  5434. else
  5435. {
  5436. RakSleep(0);
  5437. }
  5438. #else // ((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && defined(USE_WAIT_FOR_MULTIPLE_EVENTS)
  5439. #pragma message("-- RakNet: Using Sleep(). Uncomment USE_WAIT_FOR_MULTIPLE_EVENTS in RakNetDefines.h if you want to use WaitForSingleObject instead. --")
  5440. RakSleep( rakPeer->threadSleepTimer );
  5441. #endif
  5442. */
  5443. }
  5444. rakPeer->isMainLoopThreadActive = false;
  5445. /*
  5446. #ifdef _WIN32
  5447. #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
  5448. CloseHandle(timerHandle);
  5449. #endif
  5450. #endif
  5451. */
  5452. return 0;
  5453. }
  5454. void RakPeer::CallPluginCallbacks(DataStructures::List<PluginInterface2*> &pluginList, Packet *packet)
  5455. {
  5456. for (unsigned int i=0; i < pluginList.Size(); i++)
  5457. {
  5458. switch (packet->data[0])
  5459. {
  5460. case ID_DISCONNECTION_NOTIFICATION:
  5461. pluginList[i]->OnClosedConnection(packet->systemAddress, packet->guid, LCR_DISCONNECTION_NOTIFICATION);
  5462. break;
  5463. case ID_CONNECTION_LOST:
  5464. pluginList[i]->OnClosedConnection(packet->systemAddress, packet->guid, LCR_CONNECTION_LOST);
  5465. break;
  5466. case ID_NEW_INCOMING_CONNECTION:
  5467. pluginList[i]->OnNewConnection(packet->systemAddress, packet->guid, true);
  5468. break;
  5469. case ID_CONNECTION_REQUEST_ACCEPTED:
  5470. pluginList[i]->OnNewConnection(packet->systemAddress, packet->guid, false);
  5471. break;
  5472. case ID_CONNECTION_ATTEMPT_FAILED:
  5473. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_CONNECTION_ATTEMPT_FAILED);
  5474. break;
  5475. case ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY:
  5476. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY);
  5477. break;
  5478. case ID_OUR_SYSTEM_REQUIRES_SECURITY:
  5479. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_OUR_SYSTEM_REQUIRES_SECURITY);
  5480. break;
  5481. case ID_PUBLIC_KEY_MISMATCH:
  5482. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_PUBLIC_KEY_MISMATCH);
  5483. break;
  5484. case ID_ALREADY_CONNECTED:
  5485. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_ALREADY_CONNECTED);
  5486. break;
  5487. case ID_NO_FREE_INCOMING_CONNECTIONS:
  5488. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_NO_FREE_INCOMING_CONNECTIONS);
  5489. break;
  5490. case ID_CONNECTION_BANNED:
  5491. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_CONNECTION_BANNED);
  5492. break;
  5493. case ID_INVALID_PASSWORD:
  5494. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_INVALID_PASSWORD);
  5495. break;
  5496. case ID_INCOMPATIBLE_PROTOCOL_VERSION:
  5497. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_INCOMPATIBLE_PROTOCOL);
  5498. break;
  5499. case ID_IP_RECENTLY_CONNECTED:
  5500. pluginList[i]->OnFailedConnectionAttempt(packet, FCAR_IP_RECENTLY_CONNECTED);
  5501. break;
  5502. }
  5503. }
  5504. }
  5505. void RakPeer::FillIPList(void)
  5506. {
  5507. if (ipList[0]!=UNASSIGNED_SYSTEM_ADDRESS)
  5508. return;
  5509. // Fill out ipList structure
  5510. #if !defined(WINDOWS_STORE_RT)
  5511. RakNetSocket2::GetMyIP( ipList );
  5512. #endif
  5513. // Sort the addresses from lowest to highest
  5514. int startingIdx = 0;
  5515. while (startingIdx < MAXIMUM_NUMBER_OF_INTERNAL_IDS-1 && ipList[startingIdx] != UNASSIGNED_SYSTEM_ADDRESS)
  5516. {
  5517. int lowestIdx = startingIdx;
  5518. for (int curIdx = startingIdx + 1; curIdx < MAXIMUM_NUMBER_OF_INTERNAL_IDS-1 && ipList[curIdx] != UNASSIGNED_SYSTEM_ADDRESS; curIdx++ )
  5519. {
  5520. if (ipList[curIdx] < ipList[startingIdx])
  5521. {
  5522. lowestIdx = curIdx;
  5523. }
  5524. }
  5525. if (startingIdx != lowestIdx)
  5526. {
  5527. SystemAddress temp = ipList[startingIdx];
  5528. ipList[startingIdx] = ipList[lowestIdx];
  5529. ipList[lowestIdx] = temp;
  5530. }
  5531. ++startingIdx;
  5532. }
  5533. }
  5534. // #if defined(RMO_NEW_UNDEF_ALLOCATING_QUEUE)
  5535. // #pragma pop_macro("new")
  5536. // #undef RMO_NEW_UNDEF_ALLOCATING_QUEUE
  5537. // #endif
  5538. #ifdef _MSC_VER
  5539. #pragma warning( pop )
  5540. #endif
粤ICP备19079148号