GCDAsyncSocket.m 182 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969
  1. //
  2. // GCDAsyncSocket.m
  3. //
  4. // This class is in the public domain.
  5. // Originally created by Robbie Hanson in Q4 2010.
  6. // Updated and maintained by Deusty LLC and the Mac development community.
  7. //
  8. // http://code.google.com/p/cocoaasyncsocket/
  9. //
  10. #import "GCDAsyncSocket.h"
  11. #if TARGET_OS_IPHONE
  12. #import <CFNetwork/CFNetwork.h>
  13. #endif
  14. #import <arpa/inet.h>
  15. #import <fcntl.h>
  16. #import <ifaddrs.h>
  17. #import <netdb.h>
  18. #import <netinet/in.h>
  19. #import <net/if.h>
  20. #import <sys/socket.h>
  21. #import <sys/types.h>
  22. #import <sys/ioctl.h>
  23. #import <sys/poll.h>
  24. #import <sys/uio.h>
  25. #import <unistd.h>
  26. #if 0
  27. // Logging Enabled - See log level below
  28. // Logging uses the CocoaLumberjack framework (which is also GCD based).
  29. // http://code.google.com/p/cocoalumberjack/
  30. //
  31. // It allows us to do a lot of logging without significantly slowing down the code.
  32. #import "DDLog.h"
  33. #define LogAsync YES
  34. #define LogContext 65535
  35. #define LogObjc(flg, frmt, ...) LOG_OBJC_MAYBE(LogAsync, logLevel, flg, LogContext, frmt, ##__VA_ARGS__)
  36. #define LogC(flg, frmt, ...) LOG_C_MAYBE(LogAsync, logLevel, flg, LogContext, frmt, ##__VA_ARGS__)
  37. #define LogError(frmt, ...) LogObjc(LOG_FLAG_ERROR, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__)
  38. #define LogWarn(frmt, ...) LogObjc(LOG_FLAG_WARN, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__)
  39. #define LogInfo(frmt, ...) LogObjc(LOG_FLAG_INFO, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__)
  40. #define LogVerbose(frmt, ...) LogObjc(LOG_FLAG_VERBOSE, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__)
  41. #define LogCError(frmt, ...) LogC(LOG_FLAG_ERROR, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__)
  42. #define LogCWarn(frmt, ...) LogC(LOG_FLAG_WARN, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__)
  43. #define LogCInfo(frmt, ...) LogC(LOG_FLAG_INFO, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__)
  44. #define LogCVerbose(frmt, ...) LogC(LOG_FLAG_VERBOSE, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__)
  45. #define LogTrace() LogObjc(LOG_FLAG_VERBOSE, @"%@: %@", THIS_FILE, THIS_METHOD)
  46. #define LogCTrace() LogC(LOG_FLAG_VERBOSE, @"%@: %s", THIS_FILE, __FUNCTION__)
  47. // Log levels : off, error, warn, info, verbose
  48. static const int logLevel = LOG_LEVEL_VERBOSE;
  49. #else
  50. // Logging Disabled
  51. #define LogError(frmt, ...) {}
  52. #define LogWarn(frmt, ...) {}
  53. #define LogInfo(frmt, ...) {}
  54. #define LogVerbose(frmt, ...) {}
  55. #define LogCError(frmt, ...) {}
  56. #define LogCWarn(frmt, ...) {}
  57. #define LogCInfo(frmt, ...) {}
  58. #define LogCVerbose(frmt, ...) {}
  59. #define LogTrace() {}
  60. #define LogCTrace(frmt, ...) {}
  61. #endif
  62. /**
  63. * Seeing a return statements within an inner block
  64. * can sometimes be mistaken for a return point of the enclosing method.
  65. * This makes inline blocks a bit easier to read.
  66. **/
  67. #define return_from_block return
  68. /**
  69. * A socket file descriptor is really just an integer.
  70. * It represents the index of the socket within the kernel.
  71. * This makes invalid file descriptor comparisons easier to read.
  72. **/
  73. #define SOCKET_NULL -1
  74. NSString *const GCDAsyncSocketException = @"GCDAsyncSocketException";
  75. NSString *const GCDAsyncSocketErrorDomain = @"GCDAsyncSocketErrorDomain";
  76. #if !TARGET_OS_IPHONE
  77. NSString *const GCDAsyncSocketSSLCipherSuites = @"GCDAsyncSocketSSLCipherSuites";
  78. NSString *const GCDAsyncSocketSSLDiffieHellmanParameters = @"GCDAsyncSocketSSLDiffieHellmanParameters";
  79. #endif
  80. enum GCDAsyncSocketFlags
  81. {
  82. kSocketStarted = 1 << 0, // If set, socket has been started (accepting/connecting)
  83. kConnected = 1 << 1, // If set, the socket is connected
  84. kForbidReadsWrites = 1 << 2, // If set, no new reads or writes are allowed
  85. kReadsPaused = 1 << 3, // If set, reads are paused due to possible timeout
  86. kWritesPaused = 1 << 4, // If set, writes are paused due to possible timeout
  87. kDisconnectAfterReads = 1 << 5, // If set, disconnect after no more reads are queued
  88. kDisconnectAfterWrites = 1 << 6, // If set, disconnect after no more writes are queued
  89. kSocketCanAcceptBytes = 1 << 7, // If set, we know socket can accept bytes. If unset, it's unknown.
  90. kReadSourceSuspended = 1 << 8, // If set, the read source is suspended
  91. kWriteSourceSuspended = 1 << 9, // If set, the write source is suspended
  92. kQueuedTLS = 1 << 10, // If set, we've queued an upgrade to TLS
  93. kStartingReadTLS = 1 << 11, // If set, we're waiting for TLS negotiation to complete
  94. kStartingWriteTLS = 1 << 12, // If set, we're waiting for TLS negotiation to complete
  95. kSocketSecure = 1 << 13, // If set, socket is using secure communication via SSL/TLS
  96. kSocketHasReadEOF = 1 << 14, // If set, we have read EOF from socket
  97. kReadStreamClosed = 1 << 15, // If set, we've read EOF plus prebuffer has been drained
  98. #if TARGET_OS_IPHONE
  99. kAddedStreamListener = 1 << 16, // If set, CFStreams have been added to listener thread
  100. kSecureSocketHasBytesAvailable = 1 << 17, // If set, CFReadStream has notified us of bytes available
  101. #endif
  102. };
  103. enum GCDAsyncSocketConfig
  104. {
  105. kIPv4Disabled = 1 << 0, // If set, IPv4 is disabled
  106. kIPv6Disabled = 1 << 1, // If set, IPv6 is disabled
  107. kPreferIPv6 = 1 << 2, // If set, IPv6 is preferred over IPv4
  108. kAllowHalfDuplexConnection = 1 << 3, // If set, the socket will stay open even if the read stream closes
  109. };
  110. #if TARGET_OS_IPHONE
  111. static NSThread *listenerThread; // Used for CFStreams
  112. #endif
  113. @interface GCDAsyncSocket (Private)
  114. // Accepting
  115. - (BOOL)doAccept:(int)socketFD;
  116. // Connecting
  117. - (void)startConnectTimeout:(NSTimeInterval)timeout;
  118. - (void)endConnectTimeout;
  119. - (void)doConnectTimeout;
  120. - (void)lookup:(int)aConnectIndex host:(NSString *)host port:(uint16_t)port;
  121. - (void)lookup:(int)aConnectIndex didSucceedWithAddress4:(NSData *)address4 address6:(NSData *)address6;
  122. - (void)lookup:(int)aConnectIndex didFail:(NSError *)error;
  123. - (BOOL)connectWithAddress4:(NSData *)address4 address6:(NSData *)address6 error:(NSError **)errPtr;
  124. - (void)didConnect:(int)aConnectIndex;
  125. - (void)didNotConnect:(int)aConnectIndex error:(NSError *)error;
  126. // Disconnect
  127. - (void)closeWithError:(NSError *)error;
  128. - (void)close;
  129. - (void)maybeClose;
  130. // Errors
  131. - (NSError *)badConfigError:(NSString *)msg;
  132. - (NSError *)badParamError:(NSString *)msg;
  133. - (NSError *)gaiError:(int)gai_error;
  134. - (NSError *)errnoError;
  135. - (NSError *)errnoErrorWithReason:(NSString *)reason;
  136. - (NSError *)connectTimeoutError;
  137. - (NSError *)otherError:(NSString *)msg;
  138. // Diagnostics
  139. - (NSString *)connectedHost4;
  140. - (NSString *)connectedHost6;
  141. - (uint16_t)connectedPort4;
  142. - (uint16_t)connectedPort6;
  143. - (NSString *)localHost4;
  144. - (NSString *)localHost6;
  145. - (uint16_t)localPort4;
  146. - (uint16_t)localPort6;
  147. - (NSString *)connectedHostFromSocket4:(int)socketFD;
  148. - (NSString *)connectedHostFromSocket6:(int)socketFD;
  149. - (uint16_t)connectedPortFromSocket4:(int)socketFD;
  150. - (uint16_t)connectedPortFromSocket6:(int)socketFD;
  151. - (NSString *)localHostFromSocket4:(int)socketFD;
  152. - (NSString *)localHostFromSocket6:(int)socketFD;
  153. - (uint16_t)localPortFromSocket4:(int)socketFD;
  154. - (uint16_t)localPortFromSocket6:(int)socketFD;
  155. // Utilities
  156. - (void)getInterfaceAddress4:(NSMutableData **)addr4Ptr
  157. address6:(NSMutableData **)addr6Ptr
  158. fromDescription:(NSString *)interfaceDescription
  159. port:(uint16_t)port;
  160. - (void)setupReadAndWriteSourcesForNewlyConnectedSocket:(int)socketFD;
  161. - (void)suspendReadSource;
  162. - (void)resumeReadSource;
  163. - (void)suspendWriteSource;
  164. - (void)resumeWriteSource;
  165. // Reading
  166. - (void)maybeDequeueRead;
  167. - (void)flushSSLBuffers;
  168. - (void)doReadData;
  169. - (void)doReadEOF;
  170. - (void)completeCurrentRead;
  171. - (void)endCurrentRead;
  172. - (void)setupReadTimerWithTimeout:(NSTimeInterval)timeout;
  173. - (void)doReadTimeout;
  174. - (void)doReadTimeoutWithExtension:(NSTimeInterval)timeoutExtension;
  175. // Writing
  176. - (void)maybeDequeueWrite;
  177. - (void)doWriteData;
  178. - (void)completeCurrentWrite;
  179. - (void)endCurrentWrite;
  180. - (void)setupWriteTimerWithTimeout:(NSTimeInterval)timeout;
  181. - (void)doWriteTimeout;
  182. - (void)doWriteTimeoutWithExtension:(NSTimeInterval)timeoutExtension;
  183. // Security
  184. - (void)maybeStartTLS;
  185. #if !TARGET_OS_IPHONE
  186. - (void)continueSSLHandshake;
  187. #endif
  188. // CFStream
  189. #if TARGET_OS_IPHONE
  190. + (void)startListenerThreadIfNeeded;
  191. - (BOOL)createReadAndWriteStream;
  192. - (BOOL)registerForStreamCallbacksIncludingReadWrite:(BOOL)includeReadWrite;
  193. - (BOOL)addStreamsToRunLoop;
  194. - (BOOL)openStreams;
  195. - (void)removeStreamsFromRunLoop;
  196. #endif
  197. // Class Methods
  198. + (NSString *)hostFromSockaddr4:(const struct sockaddr_in *)pSockaddr4;
  199. + (NSString *)hostFromSockaddr6:(const struct sockaddr_in6 *)pSockaddr6;
  200. + (uint16_t)portFromSockaddr4:(const struct sockaddr_in *)pSockaddr4;
  201. + (uint16_t)portFromSockaddr6:(const struct sockaddr_in6 *)pSockaddr6;
  202. @end
  203. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  204. #pragma mark -
  205. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  206. /**
  207. * The GCDAsyncReadPacket encompasses the instructions for any given read.
  208. * The content of a read packet allows the code to determine if we're:
  209. * - reading to a certain length
  210. * - reading to a certain separator
  211. * - or simply reading the first chunk of available data
  212. **/
  213. @interface GCDAsyncReadPacket : NSObject
  214. {
  215. @public
  216. NSMutableData *buffer;
  217. NSUInteger startOffset;
  218. NSUInteger bytesDone;
  219. NSUInteger maxLength;
  220. NSTimeInterval timeout;
  221. NSUInteger readLength;
  222. NSData *term;
  223. BOOL bufferOwner;
  224. NSUInteger originalBufferLength;
  225. long tag;
  226. }
  227. - (id)initWithData:(NSMutableData *)d
  228. startOffset:(NSUInteger)s
  229. maxLength:(NSUInteger)m
  230. timeout:(NSTimeInterval)t
  231. readLength:(NSUInteger)l
  232. terminator:(NSData *)e
  233. tag:(long)i;
  234. - (void)ensureCapacityForAdditionalDataOfLength:(NSUInteger)bytesToRead;
  235. - (NSUInteger)optimalReadLengthWithDefault:(NSUInteger)defaultValue shouldPreBuffer:(BOOL *)shouldPreBufferPtr;
  236. - (NSUInteger)readLengthForNonTermWithHint:(NSUInteger)bytesAvailable;
  237. - (NSUInteger)readLengthForTermWithHint:(NSUInteger)bytesAvailable shouldPreBuffer:(BOOL *)shouldPreBufferPtr;
  238. - (NSUInteger)readLengthForTermWithPreBuffer:(NSData *)preBuffer found:(BOOL *)foundPtr;
  239. - (NSInteger)searchForTermAfterPreBuffering:(ssize_t)numBytes;
  240. @end
  241. @implementation GCDAsyncReadPacket
  242. - (id)initWithData:(NSMutableData *)d
  243. startOffset:(NSUInteger)s
  244. maxLength:(NSUInteger)m
  245. timeout:(NSTimeInterval)t
  246. readLength:(NSUInteger)l
  247. terminator:(NSData *)e
  248. tag:(long)i
  249. {
  250. if((self = [super init]))
  251. {
  252. bytesDone = 0;
  253. maxLength = m;
  254. timeout = t;
  255. readLength = l;
  256. term = [e copy];
  257. tag = i;
  258. if (d)
  259. {
  260. buffer = [d retain];
  261. startOffset = s;
  262. bufferOwner = NO;
  263. originalBufferLength = [d length];
  264. }
  265. else
  266. {
  267. if (readLength > 0)
  268. buffer = [[NSMutableData alloc] initWithLength:readLength];
  269. else
  270. buffer = [[NSMutableData alloc] initWithLength:0];
  271. startOffset = 0;
  272. bufferOwner = YES;
  273. originalBufferLength = 0;
  274. }
  275. }
  276. return self;
  277. }
  278. /**
  279. * Increases the length of the buffer (if needed) to ensure a read of the given size will fit.
  280. **/
  281. - (void)ensureCapacityForAdditionalDataOfLength:(NSUInteger)bytesToRead
  282. {
  283. NSUInteger buffSize = [buffer length];
  284. NSUInteger buffUsed = startOffset + bytesDone;
  285. NSUInteger buffSpace = buffSize - buffUsed;
  286. if (bytesToRead > buffSpace)
  287. {
  288. NSUInteger buffInc = bytesToRead - buffSpace;
  289. [buffer increaseLengthBy:buffInc];
  290. }
  291. }
  292. /**
  293. * This method is used when we do NOT know how much data is available to be read from the socket.
  294. * This method returns the default value unless it exceeds the specified readLength or maxLength.
  295. *
  296. * Furthermore, the shouldPreBuffer decision is based upon the packet type,
  297. * and whether the returned value would fit in the current buffer without requiring a resize of the buffer.
  298. **/
  299. - (NSUInteger)optimalReadLengthWithDefault:(NSUInteger)defaultValue shouldPreBuffer:(BOOL *)shouldPreBufferPtr
  300. {
  301. NSUInteger result;
  302. if (readLength > 0)
  303. {
  304. // Read a specific length of data
  305. result = MIN(defaultValue, (readLength - bytesDone));
  306. // There is no need to prebuffer since we know exactly how much data we need to read.
  307. // Even if the buffer isn't currently big enough to fit this amount of data,
  308. // it would have to be resized eventually anyway.
  309. if (shouldPreBufferPtr)
  310. *shouldPreBufferPtr = NO;
  311. }
  312. else
  313. {
  314. // Either reading until we find a specified terminator,
  315. // or we're simply reading all available data.
  316. //
  317. // In other words, one of:
  318. //
  319. // - readDataToData packet
  320. // - readDataWithTimeout packet
  321. if (maxLength > 0)
  322. result = MIN(defaultValue, (maxLength - bytesDone));
  323. else
  324. result = defaultValue;
  325. // Since we don't know the size of the read in advance,
  326. // the shouldPreBuffer decision is based upon whether the returned value would fit
  327. // in the current buffer without requiring a resize of the buffer.
  328. //
  329. // This is because, in all likelyhood, the amount read from the socket will be less than the default value.
  330. // Thus we should avoid over-allocating the read buffer when we can simply use the pre-buffer instead.
  331. if (shouldPreBufferPtr)
  332. {
  333. NSUInteger buffSize = [buffer length];
  334. NSUInteger buffUsed = startOffset + bytesDone;
  335. NSUInteger buffSpace = buffSize - buffUsed;
  336. if (buffSpace >= result)
  337. *shouldPreBufferPtr = NO;
  338. else
  339. *shouldPreBufferPtr = YES;
  340. }
  341. }
  342. return result;
  343. }
  344. /**
  345. * For read packets without a set terminator, returns the amount of data
  346. * that can be read without exceeding the readLength or maxLength.
  347. *
  348. * The given parameter indicates the number of bytes estimated to be available on the socket,
  349. * which is taken into consideration during the calculation.
  350. *
  351. * The given hint MUST be greater than zero.
  352. **/
  353. - (NSUInteger)readLengthForNonTermWithHint:(NSUInteger)bytesAvailable
  354. {
  355. NSAssert(term == nil, @"This method does not apply to term reads");
  356. NSAssert(bytesAvailable > 0, @"Invalid parameter: bytesAvailable");
  357. if (readLength > 0)
  358. {
  359. // Read a specific length of data
  360. return MIN(bytesAvailable, (readLength - bytesDone));
  361. // No need to avoid resizing the buffer.
  362. // If the user provided their own buffer,
  363. // and told us to read a certain length of data that exceeds the size of the buffer,
  364. // then it is clear that our code will resize the buffer during the read operation.
  365. //
  366. // This method does not actually do any resizing.
  367. // The resizing will happen elsewhere if needed.
  368. }
  369. else
  370. {
  371. // Read all available data
  372. NSUInteger result = bytesAvailable;
  373. if (maxLength > 0)
  374. {
  375. result = MIN(result, (maxLength - bytesDone));
  376. }
  377. // No need to avoid resizing the buffer.
  378. // If the user provided their own buffer,
  379. // and told us to read all available data without giving us a maxLength,
  380. // then it is clear that our code might resize the buffer during the read operation.
  381. //
  382. // This method does not actually do any resizing.
  383. // The resizing will happen elsewhere if needed.
  384. return result;
  385. }
  386. }
  387. /**
  388. * For read packets with a set terminator, returns the amount of data
  389. * that can be read without exceeding the maxLength.
  390. *
  391. * The given parameter indicates the number of bytes estimated to be available on the socket,
  392. * which is taken into consideration during the calculation.
  393. *
  394. * To optimize memory allocations, mem copies, and mem moves
  395. * the shouldPreBuffer boolean value will indicate if the data should be read into a prebuffer first,
  396. * or if the data can be read directly into the read packet's buffer.
  397. **/
  398. - (NSUInteger)readLengthForTermWithHint:(NSUInteger)bytesAvailable shouldPreBuffer:(BOOL *)shouldPreBufferPtr
  399. {
  400. NSAssert(term != nil, @"This method does not apply to non-term reads");
  401. NSAssert(bytesAvailable > 0, @"Invalid parameter: bytesAvailable");
  402. NSUInteger result = bytesAvailable;
  403. if (maxLength > 0)
  404. {
  405. result = MIN(result, (maxLength - bytesDone));
  406. }
  407. // Should the data be read into the read packet's buffer, or into a pre-buffer first?
  408. //
  409. // One would imagine the preferred option is the faster one.
  410. // So which one is faster?
  411. //
  412. // Reading directly into the packet's buffer requires:
  413. // 1. Possibly resizing packet buffer (malloc/realloc)
  414. // 2. Filling buffer (read)
  415. // 3. Searching for term (memcmp)
  416. // 4. Possibly copying overflow into prebuffer (malloc/realloc, memcpy)
  417. //
  418. // Reading into prebuffer first:
  419. // 1. Possibly resizing prebuffer (malloc/realloc)
  420. // 2. Filling buffer (read)
  421. // 3. Searching for term (memcmp)
  422. // 4. Copying underflow into packet buffer (malloc/realloc, memcpy)
  423. // 5. Removing underflow from prebuffer (memmove)
  424. //
  425. // Comparing the performance of the two we can see that reading
  426. // data into the prebuffer first is slower due to the extra memove.
  427. //
  428. // However:
  429. // The implementation of NSMutableData is open source via core foundation's CFMutableData.
  430. // Decreasing the length of a mutable data object doesn't cause a realloc.
  431. // In other words, the capacity of a mutable data object can grow, but doesn't shrink.
  432. //
  433. // This means the prebuffer will rarely need a realloc.
  434. // The packet buffer, on the other hand, may often need a realloc.
  435. // This is especially true if we are the buffer owner.
  436. // Furthermore, if we are constantly realloc'ing the packet buffer,
  437. // and then moving the overflow into the prebuffer,
  438. // then we're consistently over-allocating memory for each term read.
  439. // And now we get into a bit of a tradeoff between speed and memory utilization.
  440. //
  441. // The end result is that the two perform very similarly.
  442. // And we can answer the original question very simply by another means.
  443. //
  444. // If we can read all the data directly into the packet's buffer without resizing it first,
  445. // then we do so. Otherwise we use the prebuffer.
  446. if (shouldPreBufferPtr)
  447. {
  448. NSUInteger buffSize = [buffer length];
  449. NSUInteger buffUsed = startOffset + bytesDone;
  450. if ((buffSize - buffUsed) >= result)
  451. *shouldPreBufferPtr = NO;
  452. else
  453. *shouldPreBufferPtr = YES;
  454. }
  455. return result;
  456. }
  457. /**
  458. * For read packets with a set terminator,
  459. * returns the amount of data that can be read from the given preBuffer,
  460. * without going over a terminator or the maxLength.
  461. *
  462. * It is assumed the terminator has not already been read.
  463. **/
  464. - (NSUInteger)readLengthForTermWithPreBuffer:(NSData *)preBuffer found:(BOOL *)foundPtr
  465. {
  466. NSAssert(term != nil, @"This method does not apply to non-term reads");
  467. NSAssert([preBuffer length] > 0, @"Invoked with empty pre buffer!");
  468. // We know that the terminator, as a whole, doesn't exist in our own buffer.
  469. // But it is possible that a portion of it exists in our buffer.
  470. // So we're going to look for the terminator starting with a portion of our own buffer.
  471. //
  472. // Example:
  473. //
  474. // term length = 3 bytes
  475. // bytesDone = 5 bytes
  476. // preBuffer length = 5 bytes
  477. //
  478. // If we append the preBuffer to our buffer,
  479. // it would look like this:
  480. //
  481. // ---------------------
  482. // |B|B|B|B|B|P|P|P|P|P|
  483. // ---------------------
  484. //
  485. // So we start our search here:
  486. //
  487. // ---------------------
  488. // |B|B|B|B|B|P|P|P|P|P|
  489. // -------^-^-^---------
  490. //
  491. // And move forwards...
  492. //
  493. // ---------------------
  494. // |B|B|B|B|B|P|P|P|P|P|
  495. // ---------^-^-^-------
  496. //
  497. // Until we find the terminator or reach the end.
  498. //
  499. // ---------------------
  500. // |B|B|B|B|B|P|P|P|P|P|
  501. // ---------------^-^-^-
  502. BOOL found = NO;
  503. NSUInteger termLength = [term length];
  504. NSUInteger preBufferLength = [preBuffer length];
  505. if ((bytesDone + preBufferLength) < termLength)
  506. {
  507. // Not enough data for a full term sequence yet
  508. return preBufferLength;
  509. }
  510. NSUInteger maxPreBufferLength;
  511. if (maxLength > 0) {
  512. maxPreBufferLength = MIN(preBufferLength, (maxLength - bytesDone));
  513. // Note: maxLength >= termLength
  514. }
  515. else {
  516. maxPreBufferLength = preBufferLength;
  517. }
  518. uint8_t seq[termLength];
  519. const void *termBuf = [term bytes];
  520. NSUInteger bufLen = MIN(bytesDone, (termLength - 1));
  521. uint8_t *buf = (uint8_t *)[buffer mutableBytes] + startOffset + bytesDone - bufLen;
  522. NSUInteger preLen = termLength - bufLen;
  523. const uint8_t *pre = [preBuffer bytes];
  524. NSUInteger loopCount = bufLen + maxPreBufferLength - termLength + 1; // Plus one. See example above.
  525. NSUInteger result = preBufferLength;
  526. NSUInteger i;
  527. for (i = 0; i < loopCount; i++)
  528. {
  529. if (bufLen > 0)
  530. {
  531. // Combining bytes from buffer and preBuffer
  532. memcpy(seq, buf, bufLen);
  533. memcpy(seq + bufLen, pre, preLen);
  534. if (memcmp(seq, termBuf, termLength) == 0)
  535. {
  536. result = preLen;
  537. found = YES;
  538. break;
  539. }
  540. buf++;
  541. bufLen--;
  542. preLen++;
  543. }
  544. else
  545. {
  546. // Comparing directly from preBuffer
  547. if (memcmp(pre, termBuf, termLength) == 0)
  548. {
  549. NSUInteger preOffset = pre - (const uint8_t *)[preBuffer bytes]; // pointer arithmetic
  550. result = preOffset + termLength;
  551. found = YES;
  552. break;
  553. }
  554. pre++;
  555. }
  556. }
  557. // There is no need to avoid resizing the buffer in this particular situation.
  558. if (foundPtr) *foundPtr = found;
  559. return result;
  560. }
  561. /**
  562. * For read packets with a set terminator, scans the packet buffer for the term.
  563. * It is assumed the terminator had not been fully read prior to the new bytes.
  564. *
  565. * If the term is found, the number of excess bytes after the term are returned.
  566. * If the term is not found, this method will return -1.
  567. *
  568. * Note: A return value of zero means the term was found at the very end.
  569. *
  570. * Prerequisites:
  571. * The given number of bytes have been added to the end of our buffer.
  572. * Our bytesDone variable has NOT been changed due to the prebuffered bytes.
  573. **/
  574. - (NSInteger)searchForTermAfterPreBuffering:(ssize_t)numBytes
  575. {
  576. NSAssert(term != nil, @"This method does not apply to non-term reads");
  577. // The implementation of this method is very similar to the above method.
  578. // See the above method for a discussion of the algorithm used here.
  579. uint8_t *buff = [buffer mutableBytes];
  580. NSUInteger buffLength = bytesDone + numBytes;
  581. const void *termBuff = [term bytes];
  582. NSUInteger termLength = [term length];
  583. // Note: We are dealing with unsigned integers,
  584. // so make sure the math doesn't go below zero.
  585. NSUInteger i = ((buffLength - numBytes) >= termLength) ? (buffLength - numBytes - termLength + 1) : 0;
  586. while (i + termLength <= buffLength)
  587. {
  588. uint8_t *subBuffer = buff + startOffset + i;
  589. if (memcmp(subBuffer, termBuff, termLength) == 0)
  590. {
  591. return buffLength - (i + termLength);
  592. }
  593. i++;
  594. }
  595. return -1;
  596. }
  597. - (void)dealloc
  598. {
  599. [buffer release];
  600. [term release];
  601. [super dealloc];
  602. }
  603. @end
  604. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  605. #pragma mark -
  606. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  607. /**
  608. * The GCDAsyncWritePacket encompasses the instructions for any given write.
  609. **/
  610. @interface GCDAsyncWritePacket : NSObject
  611. {
  612. @public
  613. NSData *buffer;
  614. NSUInteger bytesDone;
  615. long tag;
  616. NSTimeInterval timeout;
  617. }
  618. - (id)initWithData:(NSData *)d timeout:(NSTimeInterval)t tag:(long)i;
  619. @end
  620. @implementation GCDAsyncWritePacket
  621. - (id)initWithData:(NSData *)d timeout:(NSTimeInterval)t tag:(long)i
  622. {
  623. if((self = [super init]))
  624. {
  625. buffer = [d retain]; // Retain not copy. For performance as documented in header file.
  626. bytesDone = 0;
  627. timeout = t;
  628. tag = i;
  629. }
  630. return self;
  631. }
  632. - (void)dealloc
  633. {
  634. [buffer release];
  635. [super dealloc];
  636. }
  637. @end
  638. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  639. #pragma mark -
  640. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  641. /**
  642. * The GCDAsyncSpecialPacket encompasses special instructions for interruptions in the read/write queues.
  643. * This class my be altered to support more than just TLS in the future.
  644. **/
  645. @interface GCDAsyncSpecialPacket : NSObject
  646. {
  647. @public
  648. NSDictionary *tlsSettings;
  649. }
  650. - (id)initWithTLSSettings:(NSDictionary *)settings;
  651. @end
  652. @implementation GCDAsyncSpecialPacket
  653. - (id)initWithTLSSettings:(NSDictionary *)settings
  654. {
  655. if((self = [super init]))
  656. {
  657. tlsSettings = [settings copy];
  658. }
  659. return self;
  660. }
  661. - (void)dealloc
  662. {
  663. [tlsSettings release];
  664. [super dealloc];
  665. }
  666. @end
  667. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  668. #pragma mark -
  669. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  670. @implementation GCDAsyncSocket
  671. - (id)init
  672. {
  673. return [self initWithDelegate:nil delegateQueue:NULL socketQueue:NULL];
  674. }
  675. - (id)initWithSocketQueue:(dispatch_queue_t)sq
  676. {
  677. return [self initWithDelegate:nil delegateQueue:NULL socketQueue:sq];
  678. }
  679. - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq
  680. {
  681. return [self initWithDelegate:aDelegate delegateQueue:dq socketQueue:NULL];
  682. }
  683. - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq
  684. {
  685. if((self = [super init]))
  686. {
  687. delegate = aDelegate;
  688. if (dq)
  689. {
  690. dispatch_retain(dq);
  691. delegateQueue = dq;
  692. }
  693. socket4FD = SOCKET_NULL;
  694. socket6FD = SOCKET_NULL;
  695. connectIndex = 0;
  696. if (sq)
  697. {
  698. NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
  699. @"The given socketQueue parameter must not be a concurrent queue.");
  700. NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
  701. @"The given socketQueue parameter must not be a concurrent queue.");
  702. NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
  703. @"The given socketQueue parameter must not be a concurrent queue.");
  704. dispatch_retain(sq);
  705. socketQueue = sq;
  706. }
  707. else
  708. {
  709. socketQueue = dispatch_queue_create("GCDAsyncSocket", NULL);
  710. }
  711. readQueue = [[NSMutableArray alloc] initWithCapacity:5];
  712. currentRead = nil;
  713. writeQueue = [[NSMutableArray alloc] initWithCapacity:5];
  714. currentWrite = nil;
  715. partialReadBuffer = [[NSMutableData alloc] init];
  716. }
  717. return self;
  718. }
  719. - (void)dealloc
  720. {
  721. LogInfo(@"%@ - %@ (start)", THIS_METHOD, self);
  722. if (dispatch_get_current_queue() == socketQueue)
  723. {
  724. [self closeWithError:nil];
  725. }
  726. else
  727. {
  728. dispatch_sync(socketQueue, ^{
  729. [self closeWithError:nil];
  730. });
  731. }
  732. delegate = nil;
  733. if (delegateQueue)
  734. dispatch_release(delegateQueue);
  735. delegateQueue = NULL;
  736. dispatch_release(socketQueue);
  737. socketQueue = NULL;
  738. [readQueue release];
  739. [writeQueue release];
  740. [partialReadBuffer release];
  741. #if !TARGET_OS_IPHONE
  742. [sslReadBuffer release];
  743. #endif
  744. [userData release];
  745. LogInfo(@"%@ - %@ (finish)", THIS_METHOD, self);
  746. [super dealloc];
  747. }
  748. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  749. #pragma mark Configuration
  750. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  751. - (id)delegate
  752. {
  753. if (dispatch_get_current_queue() == socketQueue)
  754. {
  755. return delegate;
  756. }
  757. else
  758. {
  759. __block id result;
  760. dispatch_sync(socketQueue, ^{
  761. result = delegate;
  762. });
  763. return result;
  764. }
  765. }
  766. - (void)setDelegate:(id)newDelegate synchronously:(BOOL)synchronously
  767. {
  768. dispatch_block_t block = ^{
  769. delegate = newDelegate;
  770. };
  771. if (dispatch_get_current_queue() == socketQueue) {
  772. block();
  773. }
  774. else {
  775. if (synchronously)
  776. dispatch_sync(socketQueue, block);
  777. else
  778. dispatch_async(socketQueue, block);
  779. }
  780. }
  781. - (void)setDelegate:(id)newDelegate
  782. {
  783. [self setDelegate:newDelegate synchronously:NO];
  784. }
  785. - (void)synchronouslySetDelegate:(id)newDelegate
  786. {
  787. [self setDelegate:newDelegate synchronously:YES];
  788. }
  789. - (dispatch_queue_t)delegateQueue
  790. {
  791. if (dispatch_get_current_queue() == socketQueue)
  792. {
  793. return delegateQueue;
  794. }
  795. else
  796. {
  797. __block dispatch_queue_t result;
  798. dispatch_sync(socketQueue, ^{
  799. result = delegateQueue;
  800. });
  801. return result;
  802. }
  803. }
  804. - (void)setDelegateQueue:(dispatch_queue_t)newDelegateQueue synchronously:(BOOL)synchronously
  805. {
  806. dispatch_block_t block = ^{
  807. if (delegateQueue)
  808. dispatch_release(delegateQueue);
  809. if (newDelegateQueue)
  810. dispatch_retain(newDelegateQueue);
  811. delegateQueue = newDelegateQueue;
  812. };
  813. if (dispatch_get_current_queue() == socketQueue) {
  814. block();
  815. }
  816. else {
  817. if (synchronously)
  818. dispatch_sync(socketQueue, block);
  819. else
  820. dispatch_async(socketQueue, block);
  821. }
  822. }
  823. - (void)setDelegateQueue:(dispatch_queue_t)newDelegateQueue
  824. {
  825. [self setDelegateQueue:newDelegateQueue synchronously:NO];
  826. }
  827. - (void)synchronouslySetDelegateQueue:(dispatch_queue_t)newDelegateQueue
  828. {
  829. [self setDelegateQueue:newDelegateQueue synchronously:YES];
  830. }
  831. - (void)getDelegate:(id *)delegatePtr delegateQueue:(dispatch_queue_t *)delegateQueuePtr
  832. {
  833. if (dispatch_get_current_queue() == socketQueue)
  834. {
  835. if (delegatePtr) *delegatePtr = delegate;
  836. if (delegateQueuePtr) *delegateQueuePtr = delegateQueue;
  837. }
  838. else
  839. {
  840. __block id dPtr = NULL;
  841. __block dispatch_queue_t dqPtr = NULL;
  842. dispatch_sync(socketQueue, ^{
  843. dPtr = delegate;
  844. dqPtr = delegateQueue;
  845. });
  846. if (delegatePtr) *delegatePtr = dPtr;
  847. if (delegateQueuePtr) *delegateQueuePtr = dqPtr;
  848. }
  849. }
  850. - (void)setDelegate:(id)newDelegate delegateQueue:(dispatch_queue_t)newDelegateQueue synchronously:(BOOL)synchronously
  851. {
  852. dispatch_block_t block = ^{
  853. delegate = newDelegate;
  854. if (delegateQueue)
  855. dispatch_release(delegateQueue);
  856. if (newDelegateQueue)
  857. dispatch_retain(newDelegateQueue);
  858. delegateQueue = newDelegateQueue;
  859. };
  860. if (dispatch_get_current_queue() == socketQueue) {
  861. block();
  862. }
  863. else {
  864. if (synchronously)
  865. dispatch_sync(socketQueue, block);
  866. else
  867. dispatch_async(socketQueue, block);
  868. }
  869. }
  870. - (void)setDelegate:(id)newDelegate delegateQueue:(dispatch_queue_t)newDelegateQueue
  871. {
  872. [self setDelegate:newDelegate delegateQueue:newDelegateQueue synchronously:NO];
  873. }
  874. - (void)synchronouslySetDelegate:(id)newDelegate delegateQueue:(dispatch_queue_t)newDelegateQueue
  875. {
  876. [self setDelegate:newDelegate delegateQueue:newDelegateQueue synchronously:YES];
  877. }
  878. - (BOOL)autoDisconnectOnClosedReadStream
  879. {
  880. // Note: YES means kAllowHalfDuplexConnection is OFF
  881. if (dispatch_get_current_queue() == socketQueue)
  882. {
  883. return ((config & kAllowHalfDuplexConnection) == 0);
  884. }
  885. else
  886. {
  887. __block BOOL result;
  888. dispatch_sync(socketQueue, ^{
  889. result = ((config & kAllowHalfDuplexConnection) == 0);
  890. });
  891. return result;
  892. }
  893. }
  894. - (void)setAutoDisconnectOnClosedReadStream:(BOOL)flag
  895. {
  896. // Note: YES means kAllowHalfDuplexConnection is OFF
  897. dispatch_block_t block = ^{
  898. if (flag)
  899. config &= ~kAllowHalfDuplexConnection;
  900. else
  901. config |= kAllowHalfDuplexConnection;
  902. };
  903. if (dispatch_get_current_queue() == socketQueue)
  904. block();
  905. else
  906. dispatch_async(socketQueue, block);
  907. }
  908. - (BOOL)isIPv4Enabled
  909. {
  910. // Note: YES means kIPv4Disabled is OFF
  911. if (dispatch_get_current_queue() == socketQueue)
  912. {
  913. return ((config & kIPv4Disabled) == 0);
  914. }
  915. else
  916. {
  917. __block BOOL result;
  918. dispatch_sync(socketQueue, ^{
  919. result = ((config & kIPv4Disabled) == 0);
  920. });
  921. return result;
  922. }
  923. }
  924. - (void)setIPv4Enabled:(BOOL)flag
  925. {
  926. // Note: YES means kIPv4Disabled is OFF
  927. dispatch_block_t block = ^{
  928. if (flag)
  929. config &= ~kIPv4Disabled;
  930. else
  931. config |= kIPv4Disabled;
  932. };
  933. if (dispatch_get_current_queue() == socketQueue)
  934. block();
  935. else
  936. dispatch_async(socketQueue, block);
  937. }
  938. - (BOOL)isIPv6Enabled
  939. {
  940. // Note: YES means kIPv6Disabled is OFF
  941. if (dispatch_get_current_queue() == socketQueue)
  942. {
  943. return ((config & kIPv6Disabled) == 0);
  944. }
  945. else
  946. {
  947. __block BOOL result;
  948. dispatch_sync(socketQueue, ^{
  949. result = ((config & kIPv6Disabled) == 0);
  950. });
  951. return result;
  952. }
  953. }
  954. - (void)setIPv6Enabled:(BOOL)flag
  955. {
  956. // Note: YES means kIPv6Disabled is OFF
  957. dispatch_block_t block = ^{
  958. if (flag)
  959. config &= ~kIPv6Disabled;
  960. else
  961. config |= kIPv6Disabled;
  962. };
  963. if (dispatch_get_current_queue() == socketQueue)
  964. block();
  965. else
  966. dispatch_async(socketQueue, block);
  967. }
  968. - (BOOL)isIPv4PreferredOverIPv6
  969. {
  970. // Note: YES means kPreferIPv6 is OFF
  971. if (dispatch_get_current_queue() == socketQueue)
  972. {
  973. return ((config & kPreferIPv6) == 0);
  974. }
  975. else
  976. {
  977. __block BOOL result;
  978. dispatch_sync(socketQueue, ^{
  979. result = ((config & kPreferIPv6) == 0);
  980. });
  981. return result;
  982. }
  983. }
  984. - (void)setPreferIPv4OverIPv6:(BOOL)flag
  985. {
  986. // Note: YES means kPreferIPv6 is OFF
  987. dispatch_block_t block = ^{
  988. if (flag)
  989. config &= ~kPreferIPv6;
  990. else
  991. config |= kPreferIPv6;
  992. };
  993. if (dispatch_get_current_queue() == socketQueue)
  994. block();
  995. else
  996. dispatch_async(socketQueue, block);
  997. }
  998. - (id)userData
  999. {
  1000. __block id result = nil;
  1001. dispatch_block_t block = ^{
  1002. result = [userData retain];
  1003. };
  1004. if (dispatch_get_current_queue() == socketQueue)
  1005. block();
  1006. else
  1007. dispatch_sync(socketQueue, block);
  1008. return [result autorelease];
  1009. }
  1010. - (void)setUserData:(id)arbitraryUserData
  1011. {
  1012. dispatch_block_t block = ^{
  1013. if (userData != arbitraryUserData)
  1014. {
  1015. [userData release];
  1016. userData = [arbitraryUserData retain];
  1017. }
  1018. };
  1019. if (dispatch_get_current_queue() == socketQueue)
  1020. block();
  1021. else
  1022. dispatch_async(socketQueue, block);
  1023. }
  1024. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1025. #pragma mark Accepting
  1026. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1027. - (BOOL)acceptOnPort:(uint16_t)port error:(NSError **)errPtr
  1028. {
  1029. return [self acceptOnInterface:nil port:port error:errPtr];
  1030. }
  1031. - (BOOL)acceptOnInterface:(NSString *)inInterface port:(uint16_t)port error:(NSError **)errPtr
  1032. {
  1033. LogTrace();
  1034. // Just in-case interface parameter is immutable.
  1035. NSString *interface = [[inInterface copy] autorelease];
  1036. __block BOOL result = NO;
  1037. __block NSError *err = nil;
  1038. // CreateSocket Block
  1039. // This block will be invoked within the dispatch block below.
  1040. int(^createSocket)(int, NSData*) = ^int (int domain, NSData *interfaceAddr) {
  1041. int socketFD = socket(domain, SOCK_STREAM, 0);
  1042. if (socketFD == SOCKET_NULL)
  1043. {
  1044. NSString *reason = @"Error in socket() function";
  1045. err = [[self errnoErrorWithReason:reason] retain];
  1046. return SOCKET_NULL;
  1047. }
  1048. int status;
  1049. // Set socket options
  1050. status = fcntl(socketFD, F_SETFL, O_NONBLOCK);
  1051. if (status == -1)
  1052. {
  1053. NSString *reason = @"Error enabling non-blocking IO on socket (fcntl)";
  1054. err = [[self errnoErrorWithReason:reason] retain];
  1055. close(socketFD);
  1056. return SOCKET_NULL;
  1057. }
  1058. int reuseOn = 1;
  1059. status = setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuseOn, sizeof(reuseOn));
  1060. if (status == -1)
  1061. {
  1062. NSString *reason = @"Error enabling address reuse (setsockopt)";
  1063. err = [[self errnoErrorWithReason:reason] retain];
  1064. close(socketFD);
  1065. return SOCKET_NULL;
  1066. }
  1067. // Bind socket
  1068. status = bind(socketFD, (const struct sockaddr *)[interfaceAddr bytes], (socklen_t)[interfaceAddr length]);
  1069. if (status == -1)
  1070. {
  1071. NSString *reason = @"Error in bind() function";
  1072. err = [[self errnoErrorWithReason:reason] retain];
  1073. close(socketFD);
  1074. return SOCKET_NULL;
  1075. }
  1076. // Listen
  1077. status = listen(socketFD, 1024);
  1078. if (status == -1)
  1079. {
  1080. NSString *reason = @"Error in listen() function";
  1081. err = [[self errnoErrorWithReason:reason] retain];
  1082. close(socketFD);
  1083. return SOCKET_NULL;
  1084. }
  1085. return socketFD;
  1086. };
  1087. // Create dispatch block and run on socketQueue
  1088. dispatch_block_t block = ^{
  1089. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  1090. if (delegate == nil) // Must have delegate set
  1091. {
  1092. NSString *msg = @"Attempting to accept without a delegate. Set a delegate first.";
  1093. err = [[self badConfigError:msg] retain];
  1094. [pool drain];
  1095. return_from_block;
  1096. }
  1097. if (delegateQueue == NULL) // Must have delegate queue set
  1098. {
  1099. NSString *msg = @"Attempting to accept without a delegate queue. Set a delegate queue first.";
  1100. err = [[self badConfigError:msg] retain];
  1101. [pool drain];
  1102. return_from_block;
  1103. }
  1104. BOOL isIPv4Disabled = (config & kIPv4Disabled) ? YES : NO;
  1105. BOOL isIPv6Disabled = (config & kIPv6Disabled) ? YES : NO;
  1106. if (isIPv4Disabled && isIPv6Disabled) // Must have IPv4 or IPv6 enabled
  1107. {
  1108. NSString *msg = @"Both IPv4 and IPv6 have been disabled. Must enable at least one protocol first.";
  1109. err = [[self badConfigError:msg] retain];
  1110. [pool drain];
  1111. return_from_block;
  1112. }
  1113. if (![self isDisconnected]) // Must be disconnected
  1114. {
  1115. NSString *msg = @"Attempting to accept while connected or accepting connections. Disconnect first.";
  1116. err = [[self badConfigError:msg] retain];
  1117. [pool drain];
  1118. return_from_block;
  1119. }
  1120. // Clear queues (spurious read/write requests post disconnect)
  1121. [readQueue removeAllObjects];
  1122. [writeQueue removeAllObjects];
  1123. // Resolve interface from description
  1124. NSMutableData *interface4 = nil;
  1125. NSMutableData *interface6 = nil;
  1126. [self getInterfaceAddress4:&interface4 address6:&interface6 fromDescription:interface port:port];
  1127. if ((interface4 == nil) && (interface6 == nil))
  1128. {
  1129. NSString *msg = @"Unknown interface. Specify valid interface by name (e.g. \"en1\") or IP address.";
  1130. err = [[self badParamError:msg] retain];
  1131. [pool drain];
  1132. return_from_block;
  1133. }
  1134. if (isIPv4Disabled && (interface6 == nil))
  1135. {
  1136. NSString *msg = @"IPv4 has been disabled and specified interface doesn't support IPv6.";
  1137. err = [[self badParamError:msg] retain];
  1138. [pool drain];
  1139. return_from_block;
  1140. }
  1141. if (isIPv6Disabled && (interface4 == nil))
  1142. {
  1143. NSString *msg = @"IPv6 has been disabled and specified interface doesn't support IPv4.";
  1144. err = [[self badParamError:msg] retain];
  1145. [pool drain];
  1146. return_from_block;
  1147. }
  1148. BOOL enableIPv4 = !isIPv4Disabled && (interface4 != nil);
  1149. BOOL enableIPv6 = !isIPv6Disabled && (interface6 != nil);
  1150. // Create sockets, configure, bind, and listen
  1151. if (enableIPv4)
  1152. {
  1153. LogVerbose(@"Creating IPv4 socket");
  1154. socket4FD = createSocket(AF_INET, interface4);
  1155. if (socket4FD == SOCKET_NULL)
  1156. {
  1157. [pool drain];
  1158. return_from_block;
  1159. }
  1160. }
  1161. if (enableIPv6)
  1162. {
  1163. LogVerbose(@"Creating IPv6 socket");
  1164. if (enableIPv4 && (port == 0))
  1165. {
  1166. // No specific port was specified, so we allowed the OS to pick an available port for us.
  1167. // Now we need to make sure the IPv6 socket listens on the same port as the IPv4 socket.
  1168. struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)[interface6 mutableBytes];
  1169. addr6->sin6_port = htons([self localPort4]);
  1170. }
  1171. socket6FD = createSocket(AF_INET6, interface6);
  1172. if (socket6FD == SOCKET_NULL)
  1173. {
  1174. if (socket4FD != SOCKET_NULL)
  1175. {
  1176. close(socket4FD);
  1177. }
  1178. [pool drain];
  1179. return_from_block;
  1180. }
  1181. }
  1182. // Create accept sources
  1183. if (enableIPv4)
  1184. {
  1185. accept4Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socket4FD, 0, socketQueue);
  1186. int socketFD = socket4FD;
  1187. dispatch_source_t acceptSource = accept4Source;
  1188. dispatch_source_set_event_handler(accept4Source, ^{
  1189. NSAutoreleasePool *eventPool = [[NSAutoreleasePool alloc] init];
  1190. LogVerbose(@"event4Block");
  1191. unsigned long i = 0;
  1192. unsigned long numPendingConnections = dispatch_source_get_data(acceptSource);
  1193. LogVerbose(@"numPendingConnections: %lu", numPendingConnections);
  1194. while ([self doAccept:socketFD] && (++i < numPendingConnections));
  1195. [eventPool drain];
  1196. });
  1197. dispatch_source_set_cancel_handler(accept4Source, ^{
  1198. LogVerbose(@"dispatch_release(accept4Source)");
  1199. dispatch_release(acceptSource);
  1200. LogVerbose(@"close(socket4FD)");
  1201. close(socketFD);
  1202. });
  1203. LogVerbose(@"dispatch_resume(accept4Source)");
  1204. dispatch_resume(accept4Source);
  1205. }
  1206. if (enableIPv6)
  1207. {
  1208. accept6Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socket6FD, 0, socketQueue);
  1209. int socketFD = socket6FD;
  1210. dispatch_source_t acceptSource = accept6Source;
  1211. dispatch_source_set_event_handler(accept6Source, ^{
  1212. NSAutoreleasePool *eventPool = [[NSAutoreleasePool alloc] init];
  1213. LogVerbose(@"event6Block");
  1214. unsigned long i = 0;
  1215. unsigned long numPendingConnections = dispatch_source_get_data(acceptSource);
  1216. LogVerbose(@"numPendingConnections: %lu", numPendingConnections);
  1217. while ([self doAccept:socketFD] && (++i < numPendingConnections));
  1218. [eventPool drain];
  1219. });
  1220. dispatch_source_set_cancel_handler(accept6Source, ^{
  1221. LogVerbose(@"dispatch_release(accept6Source)");
  1222. dispatch_release(acceptSource);
  1223. LogVerbose(@"close(socket6FD)");
  1224. close(socketFD);
  1225. });
  1226. LogVerbose(@"dispatch_resume(accept6Source)");
  1227. dispatch_resume(accept6Source);
  1228. }
  1229. flags |= kSocketStarted;
  1230. result = YES;
  1231. [pool drain];
  1232. };
  1233. if (dispatch_get_current_queue() == socketQueue)
  1234. block();
  1235. else
  1236. dispatch_sync(socketQueue, block);
  1237. if (result == NO)
  1238. {
  1239. LogInfo(@"Error in accept: %@", err);
  1240. if (errPtr)
  1241. *errPtr = [err autorelease];
  1242. else
  1243. [err release];
  1244. }
  1245. return result;
  1246. }
  1247. - (BOOL)doAccept:(int)parentSocketFD
  1248. {
  1249. LogTrace();
  1250. BOOL isIPv4;
  1251. int childSocketFD;
  1252. NSData *childSocketAddress;
  1253. if (parentSocketFD == socket4FD)
  1254. {
  1255. isIPv4 = YES;
  1256. struct sockaddr_in addr;
  1257. socklen_t addrLen = sizeof(addr);
  1258. childSocketFD = accept(parentSocketFD, (struct sockaddr *)&addr, &addrLen);
  1259. if (childSocketFD == -1)
  1260. {
  1261. LogWarn(@"Accept failed with error: %@", [self errnoError]);
  1262. return NO;
  1263. }
  1264. childSocketAddress = [NSData dataWithBytes:&addr length:addrLen];
  1265. }
  1266. else // if (parentSocketFD == socket6FD)
  1267. {
  1268. isIPv4 = NO;
  1269. struct sockaddr_in6 addr;
  1270. socklen_t addrLen = sizeof(addr);
  1271. childSocketFD = accept(parentSocketFD, (struct sockaddr *)&addr, &addrLen);
  1272. if (childSocketFD == -1)
  1273. {
  1274. LogWarn(@"Accept failed with error: %@", [self errnoError]);
  1275. return NO;
  1276. }
  1277. childSocketAddress = [NSData dataWithBytes:&addr length:addrLen];
  1278. }
  1279. // Enable non-blocking IO on the socket
  1280. int result = fcntl(childSocketFD, F_SETFL, O_NONBLOCK);
  1281. if (result == -1)
  1282. {
  1283. LogWarn(@"Error enabling non-blocking IO on accepted socket (fcntl)");
  1284. return NO;
  1285. }
  1286. // Prevent SIGPIPE signals
  1287. int nosigpipe = 1;
  1288. setsockopt(childSocketFD, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe));
  1289. // Notify delegate
  1290. if (delegateQueue)
  1291. {
  1292. id theDelegate = delegate;
  1293. dispatch_async(delegateQueue, ^{
  1294. NSAutoreleasePool *delegatePool = [[NSAutoreleasePool alloc] init];
  1295. // Query delegate for custom socket queue
  1296. dispatch_queue_t childSocketQueue = NULL;
  1297. if ([theDelegate respondsToSelector:@selector(newSocketQueueForConnectionFromAddress:onSocket:)])
  1298. {
  1299. childSocketQueue = [theDelegate newSocketQueueForConnectionFromAddress:childSocketAddress
  1300. onSocket:self];
  1301. }
  1302. // Create GCDAsyncSocket instance for accepted socket
  1303. GCDAsyncSocket *acceptedSocket = [[GCDAsyncSocket alloc] initWithDelegate:delegate
  1304. delegateQueue:delegateQueue
  1305. socketQueue:childSocketQueue];
  1306. if (isIPv4)
  1307. acceptedSocket->socket4FD = childSocketFD;
  1308. else
  1309. acceptedSocket->socket6FD = childSocketFD;
  1310. acceptedSocket->flags = (kSocketStarted | kConnected);
  1311. // Setup read and write sources for accepted socket
  1312. dispatch_async(acceptedSocket->socketQueue, ^{
  1313. NSAutoreleasePool *socketPool = [[NSAutoreleasePool alloc] init];
  1314. [acceptedSocket setupReadAndWriteSourcesForNewlyConnectedSocket:childSocketFD];
  1315. [socketPool drain];
  1316. });
  1317. // Notify delegate
  1318. if ([theDelegate respondsToSelector:@selector(socket:didAcceptNewSocket:)])
  1319. {
  1320. [theDelegate socket:self didAcceptNewSocket:acceptedSocket];
  1321. }
  1322. // Release the socket queue returned from the delegate (it was retained by acceptedSocket)
  1323. if (childSocketQueue)
  1324. dispatch_release(childSocketQueue);
  1325. // Release the accepted socket (it should have been retained by the delegate)
  1326. [acceptedSocket release];
  1327. [delegatePool drain];
  1328. });
  1329. }
  1330. return YES;
  1331. }
  1332. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1333. #pragma mark Connecting
  1334. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1335. /**
  1336. * This method runs through the various checks required prior to a connection attempt.
  1337. * It is shared between the connectToHost and connectToAddress methods.
  1338. *
  1339. **/
  1340. - (BOOL)preConnectWithInterface:(NSString *)interface error:(NSError **)errPtr
  1341. {
  1342. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  1343. if (delegate == nil) // Must have delegate set
  1344. {
  1345. if (errPtr)
  1346. {
  1347. NSString *msg = @"Attempting to connect without a delegate. Set a delegate first.";
  1348. *errPtr = [self badConfigError:msg];
  1349. }
  1350. return NO;
  1351. }
  1352. if (delegateQueue == NULL) // Must have delegate queue set
  1353. {
  1354. if (errPtr)
  1355. {
  1356. NSString *msg = @"Attempting to connect without a delegate queue. Set a delegate queue first.";
  1357. *errPtr = [self badConfigError:msg];
  1358. }
  1359. return NO;
  1360. }
  1361. if (![self isDisconnected]) // Must be disconnected
  1362. {
  1363. if (errPtr)
  1364. {
  1365. NSString *msg = @"Attempting to connect while connected or accepting connections. Disconnect first.";
  1366. *errPtr = [self badConfigError:msg];
  1367. }
  1368. return NO;
  1369. }
  1370. BOOL isIPv4Disabled = (config & kIPv4Disabled) ? YES : NO;
  1371. BOOL isIPv6Disabled = (config & kIPv6Disabled) ? YES : NO;
  1372. if (isIPv4Disabled && isIPv6Disabled) // Must have IPv4 or IPv6 enabled
  1373. {
  1374. if (errPtr)
  1375. {
  1376. NSString *msg = @"Both IPv4 and IPv6 have been disabled. Must enable at least one protocol first.";
  1377. *errPtr = [self badConfigError:msg];
  1378. }
  1379. return NO;
  1380. }
  1381. if (interface)
  1382. {
  1383. NSMutableData *interface4 = nil;
  1384. NSMutableData *interface6 = nil;
  1385. [self getInterfaceAddress4:&interface4 address6:&interface6 fromDescription:interface port:0];
  1386. if ((interface4 == nil) && (interface6 == nil))
  1387. {
  1388. if (errPtr)
  1389. {
  1390. NSString *msg = @"Unknown interface. Specify valid interface by name (e.g. \"en1\") or IP address.";
  1391. *errPtr = [self badParamError:msg];
  1392. }
  1393. return NO;
  1394. }
  1395. if (isIPv4Disabled && (interface6 == nil))
  1396. {
  1397. if (errPtr)
  1398. {
  1399. NSString *msg = @"IPv4 has been disabled and specified interface doesn't support IPv6.";
  1400. *errPtr = [self badParamError:msg];
  1401. }
  1402. return NO;
  1403. }
  1404. if (isIPv6Disabled && (interface4 == nil))
  1405. {
  1406. if (errPtr)
  1407. {
  1408. NSString *msg = @"IPv6 has been disabled and specified interface doesn't support IPv4.";
  1409. *errPtr = [self badParamError:msg];
  1410. }
  1411. return NO;
  1412. }
  1413. connectInterface4 = [interface4 retain];
  1414. connectInterface6 = [interface6 retain];
  1415. }
  1416. // Clear queues (spurious read/write requests post disconnect)
  1417. [readQueue removeAllObjects];
  1418. [writeQueue removeAllObjects];
  1419. return YES;
  1420. }
  1421. - (BOOL)connectToHost:(NSString*)host onPort:(uint16_t)port error:(NSError **)errPtr
  1422. {
  1423. return [self connectToHost:host onPort:port withTimeout:-1 error:errPtr];
  1424. }
  1425. - (BOOL)connectToHost:(NSString *)host
  1426. onPort:(uint16_t)port
  1427. withTimeout:(NSTimeInterval)timeout
  1428. error:(NSError **)errPtr
  1429. {
  1430. return [self connectToHost:host onPort:port viaInterface:nil withTimeout:timeout error:errPtr];
  1431. }
  1432. - (BOOL)connectToHost:(NSString *)inHost
  1433. onPort:(uint16_t)port
  1434. viaInterface:(NSString *)inInterface
  1435. withTimeout:(NSTimeInterval)timeout
  1436. error:(NSError **)errPtr
  1437. {
  1438. LogTrace();
  1439. // Just in case immutable objects were passed
  1440. NSString *host = [[inHost copy] autorelease];
  1441. NSString *interface = [[inInterface copy] autorelease];
  1442. __block BOOL result = NO;
  1443. __block NSError *err = nil;
  1444. dispatch_block_t block = ^{
  1445. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  1446. // Check for problems with host parameter
  1447. if ([host length] == 0)
  1448. {
  1449. NSString *msg = @"Invalid host parameter (nil or \"\"). Should be a domain name or IP address string.";
  1450. err = [[self badParamError:msg] retain];
  1451. [pool drain];
  1452. return_from_block;
  1453. }
  1454. // Run through standard pre-connect checks
  1455. if (![self preConnectWithInterface:interface error:&err])
  1456. {
  1457. [err retain];
  1458. [pool drain];
  1459. return_from_block;
  1460. }
  1461. // We've made it past all the checks.
  1462. // It's time to start the connection process.
  1463. flags |= kSocketStarted;
  1464. LogVerbose(@"Dispatching DNS lookup...");
  1465. // It's possible that the given host parameter is actually a NSMutableString.
  1466. // So we want to copy it now, within this block that will be executed synchronously.
  1467. // This way the asynchronous lookup block below doesn't have to worry about it changing.
  1468. int aConnectIndex = connectIndex;
  1469. NSString *hostCpy = [[host copy] autorelease];
  1470. dispatch_queue_t globalConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  1471. dispatch_async(globalConcurrentQueue, ^{
  1472. NSAutoreleasePool *lookupPool = [[NSAutoreleasePool alloc] init];
  1473. [self lookup:aConnectIndex host:hostCpy port:port];
  1474. [lookupPool drain];
  1475. });
  1476. [self startConnectTimeout:timeout];
  1477. result = YES;
  1478. [pool drain];
  1479. };
  1480. if (dispatch_get_current_queue() == socketQueue)
  1481. block();
  1482. else
  1483. dispatch_sync(socketQueue, block);
  1484. if (result == NO)
  1485. {
  1486. if (errPtr)
  1487. *errPtr = [err autorelease];
  1488. else
  1489. [err release];
  1490. }
  1491. return result;
  1492. }
  1493. - (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr
  1494. {
  1495. return [self connectToAddress:remoteAddr viaInterface:nil withTimeout:-1 error:errPtr];
  1496. }
  1497. - (BOOL)connectToAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr
  1498. {
  1499. return [self connectToAddress:remoteAddr viaInterface:nil withTimeout:timeout error:errPtr];
  1500. }
  1501. - (BOOL)connectToAddress:(NSData *)inRemoteAddr
  1502. viaInterface:(NSString *)inInterface
  1503. withTimeout:(NSTimeInterval)timeout
  1504. error:(NSError **)errPtr
  1505. {
  1506. LogTrace();
  1507. // Just in case immutable objects were passed
  1508. NSData *remoteAddr = [[inRemoteAddr copy] autorelease];
  1509. NSString *interface = [[inInterface copy] autorelease];
  1510. __block BOOL result = NO;
  1511. __block NSError *err = nil;
  1512. dispatch_block_t block = ^{
  1513. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  1514. // Check for problems with remoteAddr parameter
  1515. NSData *address4 = nil;
  1516. NSData *address6 = nil;
  1517. if ([remoteAddr length] >= sizeof(struct sockaddr))
  1518. {
  1519. const struct sockaddr *sockaddr = (const struct sockaddr *)[remoteAddr bytes];
  1520. if (sockaddr->sa_family == AF_INET)
  1521. {
  1522. if ([remoteAddr length] == sizeof(struct sockaddr_in))
  1523. {
  1524. address4 = remoteAddr;
  1525. }
  1526. }
  1527. else if (sockaddr->sa_family == AF_INET6)
  1528. {
  1529. if ([remoteAddr length] == sizeof(struct sockaddr_in6))
  1530. {
  1531. address6 = remoteAddr;
  1532. }
  1533. }
  1534. }
  1535. if ((address4 == nil) && (address6 == nil))
  1536. {
  1537. NSString *msg = @"A valid IPv4 or IPv6 address was not given";
  1538. err = [[self badParamError:msg] retain];
  1539. [pool drain];
  1540. return_from_block;
  1541. }
  1542. BOOL isIPv4Disabled = (config & kIPv4Disabled) ? YES : NO;
  1543. BOOL isIPv6Disabled = (config & kIPv6Disabled) ? YES : NO;
  1544. if (isIPv4Disabled && (address4 != nil))
  1545. {
  1546. NSString *msg = @"IPv4 has been disabled and an IPv4 address was passed.";
  1547. err = [[self badParamError:msg] retain];
  1548. [pool drain];
  1549. return_from_block;
  1550. }
  1551. if (isIPv6Disabled && (address6 != nil))
  1552. {
  1553. NSString *msg = @"IPv6 has been disabled and an IPv6 address was passed.";
  1554. err = [[self badParamError:msg] retain];
  1555. [pool drain];
  1556. return_from_block;
  1557. }
  1558. // Run through standard pre-connect checks
  1559. if (![self preConnectWithInterface:interface error:&err])
  1560. {
  1561. [err retain];
  1562. [pool drain];
  1563. return_from_block;
  1564. }
  1565. // We've made it past all the checks.
  1566. // It's time to start the connection process.
  1567. if (![self connectWithAddress4:address4 address6:address6 error:&err])
  1568. {
  1569. [err retain];
  1570. [pool drain];
  1571. return_from_block;
  1572. }
  1573. flags |= kSocketStarted;
  1574. [self startConnectTimeout:timeout];
  1575. result = YES;
  1576. [pool drain];
  1577. };
  1578. if (dispatch_get_current_queue() == socketQueue)
  1579. block();
  1580. else
  1581. dispatch_sync(socketQueue, block);
  1582. if (result == NO)
  1583. {
  1584. if (errPtr)
  1585. *errPtr = [err autorelease];
  1586. else
  1587. [err release];
  1588. }
  1589. return result;
  1590. }
  1591. - (void)lookup:(int)aConnectIndex host:(NSString *)host port:(uint16_t)port
  1592. {
  1593. LogTrace();
  1594. // This method is executed on a global concurrent queue.
  1595. // It posts the results back to the socket queue.
  1596. // The lookupIndex is used to ignore the results if the connect operation was cancelled or timed out.
  1597. NSError *error = nil;
  1598. NSData *address4 = nil;
  1599. NSData *address6 = nil;
  1600. if ([host isEqualToString:@"localhost"] || [host isEqualToString:@"loopback"])
  1601. {
  1602. // Use LOOPBACK address
  1603. struct sockaddr_in nativeAddr;
  1604. nativeAddr.sin_len = sizeof(struct sockaddr_in);
  1605. nativeAddr.sin_family = AF_INET;
  1606. nativeAddr.sin_port = htons(port);
  1607. nativeAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  1608. memset(&(nativeAddr.sin_zero), 0, sizeof(nativeAddr.sin_zero));
  1609. struct sockaddr_in6 nativeAddr6;
  1610. nativeAddr6.sin6_len = sizeof(struct sockaddr_in6);
  1611. nativeAddr6.sin6_family = AF_INET6;
  1612. nativeAddr6.sin6_port = htons(port);
  1613. nativeAddr6.sin6_flowinfo = 0;
  1614. nativeAddr6.sin6_addr = in6addr_loopback;
  1615. nativeAddr6.sin6_scope_id = 0;
  1616. // Wrap the native address structures
  1617. address4 = [NSData dataWithBytes:&nativeAddr length:sizeof(nativeAddr)];
  1618. address6 = [NSData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)];
  1619. }
  1620. else
  1621. {
  1622. NSString *portStr = [NSString stringWithFormat:@"%hu", port];
  1623. struct addrinfo hints, *res, *res0;
  1624. memset(&hints, 0, sizeof(hints));
  1625. hints.ai_family = PF_UNSPEC;
  1626. hints.ai_socktype = SOCK_STREAM;
  1627. hints.ai_protocol = IPPROTO_TCP;
  1628. int gai_error = getaddrinfo([host UTF8String], [portStr UTF8String], &hints, &res0);
  1629. if (gai_error)
  1630. {
  1631. error = [self gaiError:gai_error];
  1632. }
  1633. else
  1634. {
  1635. for(res = res0; res; res = res->ai_next)
  1636. {
  1637. if ((address4 == nil) && (res->ai_family == AF_INET))
  1638. {
  1639. // Found IPv4 address
  1640. // Wrap the native address structure
  1641. address4 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];
  1642. }
  1643. else if ((address6 == nil) && (res->ai_family == AF_INET6))
  1644. {
  1645. // Found IPv6 address
  1646. // Wrap the native address structure
  1647. address6 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];
  1648. }
  1649. }
  1650. freeaddrinfo(res0);
  1651. if ((address4 == nil) && (address6 == nil))
  1652. {
  1653. error = [self gaiError:EAI_FAIL];
  1654. }
  1655. }
  1656. }
  1657. if (error)
  1658. {
  1659. dispatch_async(socketQueue, ^{
  1660. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  1661. [self lookup:aConnectIndex didFail:error];
  1662. [pool drain];
  1663. });
  1664. }
  1665. else
  1666. {
  1667. dispatch_async(socketQueue, ^{
  1668. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  1669. [self lookup:aConnectIndex didSucceedWithAddress4:address4 address6:address6];
  1670. [pool drain];
  1671. });
  1672. }
  1673. }
  1674. - (void)lookup:(int)aConnectIndex didSucceedWithAddress4:(NSData *)address4 address6:(NSData *)address6
  1675. {
  1676. LogTrace();
  1677. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  1678. NSAssert(address4 || address6, @"Expected at least one valid address");
  1679. if (aConnectIndex != connectIndex)
  1680. {
  1681. LogInfo(@"Ignoring lookupDidSucceed, already disconnected");
  1682. // The connect operation has been cancelled.
  1683. // That is, socket was disconnected, or connection has already timed out.
  1684. return;
  1685. }
  1686. // Check for problems
  1687. BOOL isIPv4Disabled = (config & kIPv4Disabled) ? YES : NO;
  1688. BOOL isIPv6Disabled = (config & kIPv6Disabled) ? YES : NO;
  1689. if (isIPv4Disabled && (address6 == nil))
  1690. {
  1691. NSString *msg = @"IPv4 has been disabled and DNS lookup found no IPv6 address.";
  1692. [self closeWithError:[self otherError:msg]];
  1693. return;
  1694. }
  1695. if (isIPv6Disabled && (address4 == nil))
  1696. {
  1697. NSString *msg = @"IPv6 has been disabled and DNS lookup found no IPv4 address.";
  1698. [self closeWithError:[self otherError:msg]];
  1699. return;
  1700. }
  1701. // Start the normal connection process
  1702. NSError *err = nil;
  1703. if (![self connectWithAddress4:address4 address6:address6 error:&err])
  1704. {
  1705. [self closeWithError:err];
  1706. }
  1707. }
  1708. /**
  1709. * This method is called if the DNS lookup fails.
  1710. * This method is executed on the socketQueue.
  1711. *
  1712. * Since the DNS lookup executed synchronously on a global concurrent queue,
  1713. * the original connection request may have already been cancelled or timed-out by the time this method is invoked.
  1714. * The lookupIndex tells us whether the lookup is still valid or not.
  1715. **/
  1716. - (void)lookup:(int)aConnectIndex didFail:(NSError *)error
  1717. {
  1718. LogTrace();
  1719. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  1720. if (aConnectIndex != connectIndex)
  1721. {
  1722. LogInfo(@"Ignoring lookup:didFail: - already disconnected");
  1723. // The connect operation has been cancelled.
  1724. // That is, socket was disconnected, or connection has already timed out.
  1725. return;
  1726. }
  1727. [self endConnectTimeout];
  1728. [self closeWithError:error];
  1729. }
  1730. - (BOOL)connectWithAddress4:(NSData *)address4 address6:(NSData *)address6 error:(NSError **)errPtr
  1731. {
  1732. LogTrace();
  1733. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  1734. LogVerbose(@"IPv4: %@:%hu", [[self class] hostFromAddress:address4], [[self class] portFromAddress:address4]);
  1735. LogVerbose(@"IPv6: %@:%hu", [[self class] hostFromAddress:address6], [[self class] portFromAddress:address6]);
  1736. // Determine socket type
  1737. BOOL preferIPv6 = (config & kPreferIPv6) ? YES : NO;
  1738. BOOL useIPv6 = ((preferIPv6 && address6) || (address4 == nil));
  1739. // Create the socket
  1740. int socketFD;
  1741. NSData *address;
  1742. NSData *connectInterface;
  1743. if (useIPv6)
  1744. {
  1745. LogVerbose(@"Creating IPv6 socket");
  1746. socket6FD = socket(AF_INET6, SOCK_STREAM, 0);
  1747. socketFD = socket6FD;
  1748. address = address6;
  1749. connectInterface = connectInterface6;
  1750. }
  1751. else
  1752. {
  1753. LogVerbose(@"Creating IPv4 socket");
  1754. socket4FD = socket(AF_INET, SOCK_STREAM, 0);
  1755. socketFD = socket4FD;
  1756. address = address4;
  1757. connectInterface = connectInterface4;
  1758. }
  1759. if (socketFD == SOCKET_NULL)
  1760. {
  1761. if (errPtr)
  1762. *errPtr = [self errnoErrorWithReason:@"Error in socket() function"];
  1763. return NO;
  1764. }
  1765. // Bind the socket to the desired interface (if needed)
  1766. if (connectInterface)
  1767. {
  1768. LogVerbose(@"Binding socket...");
  1769. if ([[self class] portFromAddress:connectInterface] > 0)
  1770. {
  1771. // Since we're going to be binding to a specific port,
  1772. // we should turn on reuseaddr to allow us to override sockets in time_wait.
  1773. int reuseOn = 1;
  1774. setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuseOn, sizeof(reuseOn));
  1775. }
  1776. const struct sockaddr *interfaceAddr = (const struct sockaddr *)[connectInterface bytes];
  1777. int result = bind(socketFD, interfaceAddr, (socklen_t)[connectInterface length]);
  1778. if (result != 0)
  1779. {
  1780. if (errPtr)
  1781. *errPtr = [self errnoErrorWithReason:@"Error in bind() function"];
  1782. return NO;
  1783. }
  1784. }
  1785. // Start the connection process in a background queue
  1786. int aConnectIndex = connectIndex;
  1787. dispatch_queue_t globalConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  1788. dispatch_async(globalConcurrentQueue, ^{
  1789. int result = connect(socketFD, (const struct sockaddr *)[address bytes], (socklen_t)[address length]);
  1790. if (result == 0)
  1791. {
  1792. dispatch_async(socketQueue, ^{
  1793. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  1794. [self didConnect:aConnectIndex];
  1795. [pool drain];
  1796. });
  1797. }
  1798. else
  1799. {
  1800. NSError *error = [self errnoErrorWithReason:@"Error in connect() function"];
  1801. dispatch_async(socketQueue, ^{
  1802. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  1803. [self didNotConnect:aConnectIndex error:error];
  1804. [pool drain];
  1805. });
  1806. }
  1807. });
  1808. LogVerbose(@"Connecting...");
  1809. return YES;
  1810. }
  1811. - (void)didConnect:(int)aConnectIndex
  1812. {
  1813. LogTrace();
  1814. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  1815. if (aConnectIndex != connectIndex)
  1816. {
  1817. LogInfo(@"Ignoring didConnect, already disconnected");
  1818. // The connect operation has been cancelled.
  1819. // That is, socket was disconnected, or connection has already timed out.
  1820. return;
  1821. }
  1822. flags |= kConnected;
  1823. [self endConnectTimeout];
  1824. #if TARGET_OS_IPHONE
  1825. // The endConnectTimeout method executed above incremented the connectIndex.
  1826. aConnectIndex = connectIndex;
  1827. #endif
  1828. // Setup read/write streams (as workaround for specific shortcomings in the iOS platform)
  1829. //
  1830. // Note:
  1831. // There may be configuration options that must be set by the delegate before opening the streams.
  1832. // The primary example is the kCFStreamNetworkServiceTypeVoIP flag, which only works on an unopened stream.
  1833. //
  1834. // Thus we wait until after the socket:didConnectToHost:port: delegate method has completed.
  1835. // This gives the delegate time to properly configure the streams if needed.
  1836. dispatch_block_t SetupStreamsPart1 = ^{
  1837. #if TARGET_OS_IPHONE
  1838. if (![self createReadAndWriteStream])
  1839. {
  1840. [self closeWithError:[self otherError:@"Error creating CFStreams"]];
  1841. return;
  1842. }
  1843. if (![self registerForStreamCallbacksIncludingReadWrite:NO])
  1844. {
  1845. [self closeWithError:[self otherError:@"Error in CFStreamSetClient"]];
  1846. return;
  1847. }
  1848. #endif
  1849. };
  1850. dispatch_block_t SetupStreamsPart2 = ^{
  1851. #if TARGET_OS_IPHONE
  1852. if (aConnectIndex != connectIndex)
  1853. {
  1854. // The socket has been disconnected.
  1855. return;
  1856. }
  1857. if (![self addStreamsToRunLoop])
  1858. {
  1859. [self closeWithError:[self otherError:@"Error in CFStreamScheduleWithRunLoop"]];
  1860. return;
  1861. }
  1862. if (![self openStreams])
  1863. {
  1864. [self closeWithError:[self otherError:@"Error creating CFStreams"]];
  1865. return;
  1866. }
  1867. #endif
  1868. };
  1869. // Notify delegate
  1870. NSString *host = [self connectedHost];
  1871. uint16_t port = [self connectedPort];
  1872. if (delegateQueue && [delegate respondsToSelector:@selector(socket:didConnectToHost:port:)])
  1873. {
  1874. SetupStreamsPart1();
  1875. id theDelegate = delegate;
  1876. dispatch_async(delegateQueue, ^{
  1877. NSAutoreleasePool *delegatePool = [[NSAutoreleasePool alloc] init];
  1878. [theDelegate socket:self didConnectToHost:host port:port];
  1879. dispatch_async(socketQueue, ^{
  1880. NSAutoreleasePool *callbackPool = [[NSAutoreleasePool alloc] init];
  1881. SetupStreamsPart2();
  1882. [callbackPool drain];
  1883. });
  1884. [delegatePool drain];
  1885. });
  1886. }
  1887. else
  1888. {
  1889. SetupStreamsPart1();
  1890. SetupStreamsPart2();
  1891. }
  1892. // Get the connected socket
  1893. int socketFD = (socket4FD != SOCKET_NULL) ? socket4FD : socket6FD;
  1894. // Enable non-blocking IO on the socket
  1895. int result = fcntl(socketFD, F_SETFL, O_NONBLOCK);
  1896. if (result == -1)
  1897. {
  1898. NSString *errMsg = @"Error enabling non-blocking IO on socket (fcntl)";
  1899. [self closeWithError:[self otherError:errMsg]];
  1900. return;
  1901. }
  1902. // Prevent SIGPIPE signals
  1903. int nosigpipe = 1;
  1904. setsockopt(socketFD, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe));
  1905. // Setup our read/write sources
  1906. [self setupReadAndWriteSourcesForNewlyConnectedSocket:socketFD];
  1907. // Dequeue any pending read/write requests
  1908. [self maybeDequeueRead];
  1909. [self maybeDequeueWrite];
  1910. }
  1911. - (void)didNotConnect:(int)aConnectIndex error:(NSError *)error
  1912. {
  1913. LogTrace();
  1914. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  1915. if (aConnectIndex != connectIndex)
  1916. {
  1917. LogInfo(@"Ignoring didNotConnect, already disconnected");
  1918. // The connect operation has been cancelled.
  1919. // That is, socket was disconnected, or connection has already timed out.
  1920. return;
  1921. }
  1922. [self endConnectTimeout];
  1923. [self closeWithError:error];
  1924. }
  1925. - (void)startConnectTimeout:(NSTimeInterval)timeout
  1926. {
  1927. if (timeout >= 0.0)
  1928. {
  1929. connectTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, socketQueue);
  1930. dispatch_source_set_event_handler(connectTimer, ^{
  1931. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  1932. [self doConnectTimeout];
  1933. [pool drain];
  1934. });
  1935. dispatch_source_t theConnectTimer = connectTimer;
  1936. dispatch_source_set_cancel_handler(connectTimer, ^{
  1937. LogVerbose(@"dispatch_release(connectTimer)");
  1938. dispatch_release(theConnectTimer);
  1939. });
  1940. dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (timeout * NSEC_PER_SEC));
  1941. dispatch_source_set_timer(connectTimer, tt, DISPATCH_TIME_FOREVER, 0);
  1942. dispatch_resume(connectTimer);
  1943. }
  1944. }
  1945. - (void)endConnectTimeout
  1946. {
  1947. LogTrace();
  1948. if (connectTimer)
  1949. {
  1950. dispatch_source_cancel(connectTimer);
  1951. connectTimer = NULL;
  1952. }
  1953. // Increment connectIndex.
  1954. // This will prevent us from processing results from any related background asynchronous operations.
  1955. //
  1956. // Note: This should be called from close method even if connectTimer is NULL.
  1957. // This is because one might disconnect a socket prior to a successful connection which had no timeout.
  1958. connectIndex++;
  1959. if (connectInterface4)
  1960. {
  1961. [connectInterface4 release];
  1962. connectInterface4 = nil;
  1963. }
  1964. if (connectInterface6)
  1965. {
  1966. [connectInterface6 release];
  1967. connectInterface6 = nil;
  1968. }
  1969. }
  1970. - (void)doConnectTimeout
  1971. {
  1972. LogTrace();
  1973. [self endConnectTimeout];
  1974. [self closeWithError:[self connectTimeoutError]];
  1975. }
  1976. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1977. #pragma mark Disconnecting
  1978. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1979. - (void)closeWithError:(NSError *)error
  1980. {
  1981. LogTrace();
  1982. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  1983. [self endConnectTimeout];
  1984. if (currentRead != nil) [self endCurrentRead];
  1985. if (currentWrite != nil) [self endCurrentWrite];
  1986. [readQueue removeAllObjects];
  1987. [writeQueue removeAllObjects];
  1988. [partialReadBuffer setLength:0];
  1989. #if TARGET_OS_IPHONE
  1990. {
  1991. if (readStream || writeStream)
  1992. {
  1993. [self removeStreamsFromRunLoop];
  1994. if (readStream)
  1995. {
  1996. CFReadStreamSetClient(readStream, kCFStreamEventNone, NULL, NULL);
  1997. CFReadStreamClose(readStream);
  1998. CFRelease(readStream);
  1999. readStream = NULL;
  2000. }
  2001. if (writeStream)
  2002. {
  2003. CFWriteStreamSetClient(writeStream, kCFStreamEventNone, NULL, NULL);
  2004. CFWriteStreamClose(writeStream);
  2005. CFRelease(writeStream);
  2006. writeStream = NULL;
  2007. }
  2008. }
  2009. }
  2010. #else
  2011. {
  2012. [sslReadBuffer setLength:0];
  2013. if (sslContext)
  2014. {
  2015. // Getting a linker error here about SSLDisposeContext?
  2016. // You need to add the Security Framework to your application.
  2017. SSLDisposeContext(sslContext);
  2018. sslContext = NULL;
  2019. }
  2020. }
  2021. #endif
  2022. // For some crazy reason (in my opinion), cancelling a dispatch source doesn't
  2023. // invoke the cancel handler if the dispatch source is paused.
  2024. // So we have to unpause the source if needed.
  2025. // This allows the cancel handler to be run, which in turn releases the source and closes the socket.
  2026. if (accept4Source)
  2027. {
  2028. LogVerbose(@"dispatch_source_cancel(accept4Source)");
  2029. dispatch_source_cancel(accept4Source);
  2030. // We never suspend accept4Source
  2031. accept4Source = NULL;
  2032. }
  2033. if (accept6Source)
  2034. {
  2035. LogVerbose(@"dispatch_source_cancel(accept6Source)");
  2036. dispatch_source_cancel(accept6Source);
  2037. // We never suspend accept6Source
  2038. accept6Source = NULL;
  2039. }
  2040. if (!readSource && !writeSource) {
  2041. LogVerbose(@"manually closing close");
  2042. if (socket4FD) {
  2043. close(socket4FD);
  2044. }
  2045. if (socket6FD) {
  2046. close(socket6FD);
  2047. }
  2048. }
  2049. if (readSource)
  2050. {
  2051. LogVerbose(@"dispatch_source_cancel(readSource)");
  2052. dispatch_source_cancel(readSource);
  2053. [self resumeReadSource];
  2054. readSource = NULL;
  2055. }
  2056. if (writeSource)
  2057. {
  2058. LogVerbose(@"dispatch_source_cancel(writeSource)");
  2059. dispatch_source_cancel(writeSource);
  2060. [self resumeWriteSource];
  2061. writeSource = NULL;
  2062. }
  2063. // The sockets will be closed by the cancel handlers of the corresponding source
  2064. socket4FD = SOCKET_NULL;
  2065. socket6FD = SOCKET_NULL;
  2066. // If the client has passed the connect/accept method, then the connection has at least begun.
  2067. // Notify delegate that it is now ending.
  2068. BOOL shouldCallDelegate = (flags & kSocketStarted);
  2069. // Clear stored socket info and all flags (config remains as is)
  2070. socketFDBytesAvailable = 0;
  2071. flags = 0;
  2072. if (shouldCallDelegate)
  2073. {
  2074. if (delegateQueue && [delegate respondsToSelector: @selector(socketDidDisconnect:withError:)])
  2075. {
  2076. id theDelegate = delegate;
  2077. dispatch_async(delegateQueue, ^{
  2078. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2079. [theDelegate socketDidDisconnect:self withError:error];
  2080. [pool drain];
  2081. });
  2082. }
  2083. }
  2084. }
  2085. - (void)disconnect
  2086. {
  2087. dispatch_block_t block = ^{
  2088. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2089. if (flags & kSocketStarted)
  2090. {
  2091. [self closeWithError:nil];
  2092. }
  2093. [pool drain];
  2094. };
  2095. // Synchronous disconnection, as documented in the header file
  2096. if (dispatch_get_current_queue() == socketQueue)
  2097. block();
  2098. else
  2099. dispatch_sync(socketQueue, block);
  2100. }
  2101. - (void)disconnectAfterReading
  2102. {
  2103. dispatch_async(socketQueue, ^{
  2104. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2105. if (flags & kSocketStarted)
  2106. {
  2107. flags |= (kForbidReadsWrites | kDisconnectAfterReads);
  2108. [self maybeClose];
  2109. }
  2110. [pool drain];
  2111. });
  2112. }
  2113. - (void)disconnectAfterWriting
  2114. {
  2115. dispatch_async(socketQueue, ^{
  2116. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2117. if (flags & kSocketStarted)
  2118. {
  2119. flags |= (kForbidReadsWrites | kDisconnectAfterWrites);
  2120. [self maybeClose];
  2121. }
  2122. [pool drain];
  2123. });
  2124. }
  2125. - (void)disconnectAfterReadingAndWriting
  2126. {
  2127. dispatch_async(socketQueue, ^{
  2128. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2129. if (flags & kSocketStarted)
  2130. {
  2131. flags |= (kForbidReadsWrites | kDisconnectAfterReads | kDisconnectAfterWrites);
  2132. [self maybeClose];
  2133. }
  2134. [pool drain];
  2135. });
  2136. }
  2137. /**
  2138. * Closes the socket if possible.
  2139. * That is, if all writes have completed, and we're set to disconnect after writing,
  2140. * or if all reads have completed, and we're set to disconnect after reading.
  2141. **/
  2142. - (void)maybeClose
  2143. {
  2144. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  2145. BOOL shouldClose = NO;
  2146. if (flags & kDisconnectAfterReads)
  2147. {
  2148. if (([readQueue count] == 0) && (currentRead == nil))
  2149. {
  2150. if (flags & kDisconnectAfterWrites)
  2151. {
  2152. if (([writeQueue count] == 0) && (currentWrite == nil))
  2153. {
  2154. shouldClose = YES;
  2155. }
  2156. }
  2157. else
  2158. {
  2159. shouldClose = YES;
  2160. }
  2161. }
  2162. }
  2163. else if (flags & kDisconnectAfterWrites)
  2164. {
  2165. if (([writeQueue count] == 0) && (currentWrite == nil))
  2166. {
  2167. shouldClose = YES;
  2168. }
  2169. }
  2170. if (shouldClose)
  2171. {
  2172. [self closeWithError:nil];
  2173. }
  2174. }
  2175. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2176. #pragma mark Errors
  2177. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2178. - (NSError *)badConfigError:(NSString *)errMsg
  2179. {
  2180. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2181. return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketBadConfigError userInfo:userInfo];
  2182. }
  2183. - (NSError *)badParamError:(NSString *)errMsg
  2184. {
  2185. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2186. return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketBadParamError userInfo:userInfo];
  2187. }
  2188. - (NSError *)gaiError:(int)gai_error
  2189. {
  2190. NSString *errMsg = [NSString stringWithCString:gai_strerror(gai_error) encoding:NSASCIIStringEncoding];
  2191. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2192. return [NSError errorWithDomain:@"kCFStreamErrorDomainNetDB" code:gai_error userInfo:userInfo];
  2193. }
  2194. - (NSError *)errnoErrorWithReason:(NSString *)reason
  2195. {
  2196. NSString *errMsg = [NSString stringWithUTF8String:strerror(errno)];
  2197. NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:errMsg, NSLocalizedDescriptionKey,
  2198. reason, NSLocalizedFailureReasonErrorKey, nil];
  2199. return [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:userInfo];
  2200. }
  2201. - (NSError *)errnoError
  2202. {
  2203. NSString *errMsg = [NSString stringWithUTF8String:strerror(errno)];
  2204. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2205. return [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:userInfo];
  2206. }
  2207. - (NSError *)sslError:(OSStatus)ssl_error
  2208. {
  2209. NSString *msg = @"Error code definition can be found in Apple's SecureTransport.h";
  2210. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:msg forKey:NSLocalizedRecoverySuggestionErrorKey];
  2211. return [NSError errorWithDomain:@"kCFStreamErrorDomainSSL" code:ssl_error userInfo:userInfo];
  2212. }
  2213. - (NSError *)connectTimeoutError
  2214. {
  2215. NSString *errMsg = NSLocalizedStringWithDefaultValue(@"GCDAsyncSocketConnectTimeoutError",
  2216. @"GCDAsyncSocket", [NSBundle mainBundle],
  2217. @"Attempt to connect to host timed out", nil);
  2218. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2219. return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketConnectTimeoutError userInfo:userInfo];
  2220. }
  2221. /**
  2222. * Returns a standard AsyncSocket maxed out error.
  2223. **/
  2224. - (NSError *)readMaxedOutError
  2225. {
  2226. NSString *errMsg = NSLocalizedStringWithDefaultValue(@"GCDAsyncSocketReadMaxedOutError",
  2227. @"GCDAsyncSocket", [NSBundle mainBundle],
  2228. @"Read operation reached set maximum length", nil);
  2229. NSDictionary *info = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2230. return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketReadMaxedOutError userInfo:info];
  2231. }
  2232. /**
  2233. * Returns a standard AsyncSocket write timeout error.
  2234. **/
  2235. - (NSError *)readTimeoutError
  2236. {
  2237. NSString *errMsg = NSLocalizedStringWithDefaultValue(@"GCDAsyncSocketReadTimeoutError",
  2238. @"GCDAsyncSocket", [NSBundle mainBundle],
  2239. @"Read operation timed out", nil);
  2240. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2241. return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketReadTimeoutError userInfo:userInfo];
  2242. }
  2243. /**
  2244. * Returns a standard AsyncSocket write timeout error.
  2245. **/
  2246. - (NSError *)writeTimeoutError
  2247. {
  2248. NSString *errMsg = NSLocalizedStringWithDefaultValue(@"GCDAsyncSocketWriteTimeoutError",
  2249. @"GCDAsyncSocket", [NSBundle mainBundle],
  2250. @"Write operation timed out", nil);
  2251. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2252. return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketWriteTimeoutError userInfo:userInfo];
  2253. }
  2254. - (NSError *)connectionClosedError
  2255. {
  2256. NSString *errMsg = NSLocalizedStringWithDefaultValue(@"GCDAsyncSocketClosedError",
  2257. @"GCDAsyncSocket", [NSBundle mainBundle],
  2258. @"Socket closed by remote peer", nil);
  2259. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2260. return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketClosedError userInfo:userInfo];
  2261. }
  2262. - (NSError *)otherError:(NSString *)errMsg
  2263. {
  2264. NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
  2265. return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketOtherError userInfo:userInfo];
  2266. }
  2267. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2268. #pragma mark Diagnostics
  2269. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2270. - (BOOL)isDisconnected
  2271. {
  2272. __block BOOL result = NO;
  2273. dispatch_block_t block = ^{
  2274. result = (flags & kSocketStarted) ? NO : YES;
  2275. };
  2276. if (dispatch_get_current_queue() == socketQueue)
  2277. block();
  2278. else
  2279. dispatch_sync(socketQueue, block);
  2280. return result;
  2281. }
  2282. - (BOOL)isConnected
  2283. {
  2284. __block BOOL result = NO;
  2285. dispatch_block_t block = ^{
  2286. result = (flags & kConnected) ? YES : NO;
  2287. };
  2288. if (dispatch_get_current_queue() == socketQueue)
  2289. block();
  2290. else
  2291. dispatch_sync(socketQueue, block);
  2292. return result;
  2293. }
  2294. - (NSString *)connectedHost
  2295. {
  2296. if (dispatch_get_current_queue() == socketQueue)
  2297. {
  2298. if (socket4FD != SOCKET_NULL)
  2299. return [self connectedHostFromSocket4:socket4FD];
  2300. if (socket6FD != SOCKET_NULL)
  2301. return [self connectedHostFromSocket6:socket6FD];
  2302. return nil;
  2303. }
  2304. else
  2305. {
  2306. __block NSString *result = nil;
  2307. dispatch_sync(socketQueue, ^{
  2308. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2309. if (socket4FD != SOCKET_NULL)
  2310. result = [[self connectedHostFromSocket4:socket4FD] retain];
  2311. else if (socket6FD != SOCKET_NULL)
  2312. result = [[self connectedHostFromSocket6:socket6FD] retain];
  2313. [pool drain];
  2314. });
  2315. return [result autorelease];
  2316. }
  2317. }
  2318. - (uint16_t)connectedPort
  2319. {
  2320. if (dispatch_get_current_queue() == socketQueue)
  2321. {
  2322. if (socket4FD != SOCKET_NULL)
  2323. return [self connectedPortFromSocket4:socket4FD];
  2324. if (socket6FD != SOCKET_NULL)
  2325. return [self connectedPortFromSocket6:socket6FD];
  2326. return 0;
  2327. }
  2328. else
  2329. {
  2330. __block uint16_t result = 0;
  2331. dispatch_sync(socketQueue, ^{
  2332. // No need for autorelease pool
  2333. if (socket4FD != SOCKET_NULL)
  2334. result = [self connectedPortFromSocket4:socket4FD];
  2335. else if (socket6FD != SOCKET_NULL)
  2336. result = [self connectedPortFromSocket6:socket6FD];
  2337. });
  2338. return result;
  2339. }
  2340. }
  2341. - (NSString *)localHost
  2342. {
  2343. if (dispatch_get_current_queue() == socketQueue)
  2344. {
  2345. if (socket4FD != SOCKET_NULL)
  2346. return [self localHostFromSocket4:socket4FD];
  2347. if (socket6FD != SOCKET_NULL)
  2348. return [self localHostFromSocket6:socket6FD];
  2349. return nil;
  2350. }
  2351. else
  2352. {
  2353. __block NSString *result = nil;
  2354. dispatch_sync(socketQueue, ^{
  2355. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2356. if (socket4FD != SOCKET_NULL)
  2357. result = [[self localHostFromSocket4:socket4FD] retain];
  2358. else if (socket6FD != SOCKET_NULL)
  2359. result = [[self localHostFromSocket6:socket6FD] retain];
  2360. [pool drain];
  2361. });
  2362. return [result autorelease];
  2363. }
  2364. }
  2365. - (uint16_t)localPort
  2366. {
  2367. if (dispatch_get_current_queue() == socketQueue)
  2368. {
  2369. if (socket4FD != SOCKET_NULL)
  2370. return [self localPortFromSocket4:socket4FD];
  2371. if (socket6FD != SOCKET_NULL)
  2372. return [self localPortFromSocket6:socket6FD];
  2373. return 0;
  2374. }
  2375. else
  2376. {
  2377. __block uint16_t result = 0;
  2378. dispatch_sync(socketQueue, ^{
  2379. // No need for autorelease pool
  2380. if (socket4FD != SOCKET_NULL)
  2381. result = [self localPortFromSocket4:socket4FD];
  2382. else if (socket6FD != SOCKET_NULL)
  2383. result = [self localPortFromSocket6:socket6FD];
  2384. });
  2385. return result;
  2386. }
  2387. }
  2388. - (NSString *)connectedHost4
  2389. {
  2390. if (socket4FD != SOCKET_NULL)
  2391. return [self connectedHostFromSocket4:socket4FD];
  2392. return nil;
  2393. }
  2394. - (NSString *)connectedHost6
  2395. {
  2396. if (socket6FD != SOCKET_NULL)
  2397. return [self connectedHostFromSocket6:socket6FD];
  2398. return nil;
  2399. }
  2400. - (uint16_t)connectedPort4
  2401. {
  2402. if (socket4FD != SOCKET_NULL)
  2403. return [self connectedPortFromSocket4:socket4FD];
  2404. return 0;
  2405. }
  2406. - (uint16_t)connectedPort6
  2407. {
  2408. if (socket6FD != SOCKET_NULL)
  2409. return [self connectedPortFromSocket6:socket6FD];
  2410. return 0;
  2411. }
  2412. - (NSString *)localHost4
  2413. {
  2414. if (socket4FD != SOCKET_NULL)
  2415. return [self localHostFromSocket4:socket4FD];
  2416. return nil;
  2417. }
  2418. - (NSString *)localHost6
  2419. {
  2420. if (socket6FD != SOCKET_NULL)
  2421. return [self localHostFromSocket6:socket6FD];
  2422. return nil;
  2423. }
  2424. - (uint16_t)localPort4
  2425. {
  2426. if (socket4FD != SOCKET_NULL)
  2427. return [self localPortFromSocket4:socket4FD];
  2428. return 0;
  2429. }
  2430. - (uint16_t)localPort6
  2431. {
  2432. if (socket6FD != SOCKET_NULL)
  2433. return [self localPortFromSocket6:socket6FD];
  2434. return 0;
  2435. }
  2436. - (NSString *)connectedHostFromSocket4:(int)socketFD
  2437. {
  2438. struct sockaddr_in sockaddr4;
  2439. socklen_t sockaddr4len = sizeof(sockaddr4);
  2440. if (getpeername(socketFD, (struct sockaddr *)&sockaddr4, &sockaddr4len) < 0)
  2441. {
  2442. return nil;
  2443. }
  2444. return [[self class] hostFromSockaddr4:&sockaddr4];
  2445. }
  2446. - (NSString *)connectedHostFromSocket6:(int)socketFD
  2447. {
  2448. struct sockaddr_in6 sockaddr6;
  2449. socklen_t sockaddr6len = sizeof(sockaddr6);
  2450. if (getpeername(socketFD, (struct sockaddr *)&sockaddr6, &sockaddr6len) < 0)
  2451. {
  2452. return nil;
  2453. }
  2454. return [[self class] hostFromSockaddr6:&sockaddr6];
  2455. }
  2456. - (uint16_t)connectedPortFromSocket4:(int)socketFD
  2457. {
  2458. struct sockaddr_in sockaddr4;
  2459. socklen_t sockaddr4len = sizeof(sockaddr4);
  2460. if (getpeername(socketFD, (struct sockaddr *)&sockaddr4, &sockaddr4len) < 0)
  2461. {
  2462. return 0;
  2463. }
  2464. return [[self class] portFromSockaddr4:&sockaddr4];
  2465. }
  2466. - (uint16_t)connectedPortFromSocket6:(int)socketFD
  2467. {
  2468. struct sockaddr_in6 sockaddr6;
  2469. socklen_t sockaddr6len = sizeof(sockaddr6);
  2470. if (getpeername(socketFD, (struct sockaddr *)&sockaddr6, &sockaddr6len) < 0)
  2471. {
  2472. return 0;
  2473. }
  2474. return [[self class] portFromSockaddr6:&sockaddr6];
  2475. }
  2476. - (NSString *)localHostFromSocket4:(int)socketFD
  2477. {
  2478. struct sockaddr_in sockaddr4;
  2479. socklen_t sockaddr4len = sizeof(sockaddr4);
  2480. if (getsockname(socketFD, (struct sockaddr *)&sockaddr4, &sockaddr4len) < 0)
  2481. {
  2482. return nil;
  2483. }
  2484. return [[self class] hostFromSockaddr4:&sockaddr4];
  2485. }
  2486. - (NSString *)localHostFromSocket6:(int)socketFD
  2487. {
  2488. struct sockaddr_in6 sockaddr6;
  2489. socklen_t sockaddr6len = sizeof(sockaddr6);
  2490. if (getsockname(socketFD, (struct sockaddr *)&sockaddr6, &sockaddr6len) < 0)
  2491. {
  2492. return nil;
  2493. }
  2494. return [[self class] hostFromSockaddr6:&sockaddr6];
  2495. }
  2496. - (uint16_t)localPortFromSocket4:(int)socketFD
  2497. {
  2498. struct sockaddr_in sockaddr4;
  2499. socklen_t sockaddr4len = sizeof(sockaddr4);
  2500. if (getsockname(socketFD, (struct sockaddr *)&sockaddr4, &sockaddr4len) < 0)
  2501. {
  2502. return 0;
  2503. }
  2504. return [[self class] portFromSockaddr4:&sockaddr4];
  2505. }
  2506. - (uint16_t)localPortFromSocket6:(int)socketFD
  2507. {
  2508. struct sockaddr_in6 sockaddr6;
  2509. socklen_t sockaddr6len = sizeof(sockaddr6);
  2510. if (getsockname(socketFD, (struct sockaddr *)&sockaddr6, &sockaddr6len) < 0)
  2511. {
  2512. return 0;
  2513. }
  2514. return [[self class] portFromSockaddr6:&sockaddr6];
  2515. }
  2516. - (NSData *)connectedAddress
  2517. {
  2518. __block NSData *result = nil;
  2519. dispatch_block_t block = ^{
  2520. if (socket4FD != SOCKET_NULL)
  2521. {
  2522. struct sockaddr_in sockaddr4;
  2523. socklen_t sockaddr4len = sizeof(sockaddr4);
  2524. if (getpeername(socket4FD, (struct sockaddr *)&sockaddr4, &sockaddr4len) == 0)
  2525. {
  2526. result = [[NSData alloc] initWithBytes:&sockaddr4 length:sockaddr4len];
  2527. }
  2528. }
  2529. if (socket6FD != SOCKET_NULL)
  2530. {
  2531. struct sockaddr_in6 sockaddr6;
  2532. socklen_t sockaddr6len = sizeof(sockaddr6);
  2533. if (getpeername(socket6FD, (struct sockaddr *)&sockaddr6, &sockaddr6len) == 0)
  2534. {
  2535. result = [[NSData alloc] initWithBytes:&sockaddr6 length:sockaddr6len];
  2536. }
  2537. }
  2538. };
  2539. if (dispatch_get_current_queue() == socketQueue)
  2540. block();
  2541. else
  2542. dispatch_sync(socketQueue, block);
  2543. return [result autorelease];
  2544. }
  2545. - (NSData *)localAddress
  2546. {
  2547. __block NSData *result = nil;
  2548. dispatch_block_t block = ^{
  2549. if (socket4FD != SOCKET_NULL)
  2550. {
  2551. struct sockaddr_in sockaddr4;
  2552. socklen_t sockaddr4len = sizeof(sockaddr4);
  2553. if (getsockname(socket4FD, (struct sockaddr *)&sockaddr4, &sockaddr4len) == 0)
  2554. {
  2555. result = [[NSData alloc] initWithBytes:&sockaddr4 length:sockaddr4len];
  2556. }
  2557. }
  2558. if (socket6FD != SOCKET_NULL)
  2559. {
  2560. struct sockaddr_in6 sockaddr6;
  2561. socklen_t sockaddr6len = sizeof(sockaddr6);
  2562. if (getsockname(socket6FD, (struct sockaddr *)&sockaddr6, &sockaddr6len) == 0)
  2563. {
  2564. result = [[NSData alloc] initWithBytes:&sockaddr6 length:sockaddr6len];
  2565. }
  2566. }
  2567. };
  2568. if (dispatch_get_current_queue() == socketQueue)
  2569. block();
  2570. else
  2571. dispatch_sync(socketQueue, block);
  2572. return [result autorelease];
  2573. }
  2574. - (BOOL)isIPv4
  2575. {
  2576. if (dispatch_get_current_queue() == socketQueue)
  2577. {
  2578. return (socket4FD != SOCKET_NULL);
  2579. }
  2580. else
  2581. {
  2582. __block BOOL result = NO;
  2583. dispatch_sync(socketQueue, ^{
  2584. result = (socket4FD != SOCKET_NULL);
  2585. });
  2586. return result;
  2587. }
  2588. }
  2589. - (BOOL)isIPv6
  2590. {
  2591. if (dispatch_get_current_queue() == socketQueue)
  2592. {
  2593. return (socket6FD != SOCKET_NULL);
  2594. }
  2595. else
  2596. {
  2597. __block BOOL result = NO;
  2598. dispatch_sync(socketQueue, ^{
  2599. result = (socket6FD != SOCKET_NULL);
  2600. });
  2601. return result;
  2602. }
  2603. }
  2604. - (BOOL)isSecure
  2605. {
  2606. if (dispatch_get_current_queue() == socketQueue)
  2607. {
  2608. return (flags & kSocketSecure) ? YES : NO;
  2609. }
  2610. else
  2611. {
  2612. __block BOOL result;
  2613. dispatch_sync(socketQueue, ^{
  2614. result = (flags & kSocketSecure) ? YES : NO;
  2615. });
  2616. return result;
  2617. }
  2618. }
  2619. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2620. #pragma mark Utilities
  2621. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2622. /**
  2623. * Finds the address of an interface description.
  2624. * An inteface description may be an interface name (en0, en1, lo0) or corresponding IP (192.168.4.34).
  2625. *
  2626. * The interface description may optionally contain a port number at the end, separated by a colon.
  2627. * If a non-zero port parameter is provided, any port number in the interface description is ignored.
  2628. *
  2629. * The returned value is a 'struct sockaddr' wrapped in an NSMutableData object.
  2630. **/
  2631. - (void)getInterfaceAddress4:(NSMutableData **)interfaceAddr4Ptr
  2632. address6:(NSMutableData **)interfaceAddr6Ptr
  2633. fromDescription:(NSString *)interfaceDescription
  2634. port:(uint16_t)port
  2635. {
  2636. NSMutableData *addr4 = nil;
  2637. NSMutableData *addr6 = nil;
  2638. NSString *interface = nil;
  2639. NSArray *components = [interfaceDescription componentsSeparatedByString:@":"];
  2640. if ([components count] > 0)
  2641. {
  2642. NSString *temp = [components objectAtIndex:0];
  2643. if ([temp length] > 0)
  2644. {
  2645. interface = temp;
  2646. }
  2647. }
  2648. if ([components count] > 1 && port == 0)
  2649. {
  2650. long portL = strtol([[components objectAtIndex:1] UTF8String], NULL, 10);
  2651. if (portL > 0 && portL <= UINT16_MAX)
  2652. {
  2653. port = (uint16_t)portL;
  2654. }
  2655. }
  2656. if (interface == nil)
  2657. {
  2658. // ANY address
  2659. struct sockaddr_in sockaddr4;
  2660. memset(&sockaddr4, 0, sizeof(sockaddr4));
  2661. sockaddr4.sin_len = sizeof(sockaddr4);
  2662. sockaddr4.sin_family = AF_INET;
  2663. sockaddr4.sin_port = htons(port);
  2664. sockaddr4.sin_addr.s_addr = htonl(INADDR_ANY);
  2665. struct sockaddr_in6 sockaddr6;
  2666. memset(&sockaddr6, 0, sizeof(sockaddr6));
  2667. sockaddr6.sin6_len = sizeof(sockaddr6);
  2668. sockaddr6.sin6_family = AF_INET6;
  2669. sockaddr6.sin6_port = htons(port);
  2670. sockaddr6.sin6_addr = in6addr_any;
  2671. addr4 = [NSMutableData dataWithBytes:&sockaddr4 length:sizeof(sockaddr4)];
  2672. addr6 = [NSMutableData dataWithBytes:&sockaddr6 length:sizeof(sockaddr6)];
  2673. }
  2674. else if ([interface isEqualToString:@"localhost"] || [interface isEqualToString:@"loopback"])
  2675. {
  2676. // LOOPBACK address
  2677. struct sockaddr_in sockaddr4;
  2678. memset(&sockaddr4, 0, sizeof(sockaddr4));
  2679. sockaddr4.sin_len = sizeof(sockaddr4);
  2680. sockaddr4.sin_family = AF_INET;
  2681. sockaddr4.sin_port = htons(port);
  2682. sockaddr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  2683. struct sockaddr_in6 sockaddr6;
  2684. memset(&sockaddr6, 0, sizeof(sockaddr6));
  2685. sockaddr6.sin6_len = sizeof(sockaddr6);
  2686. sockaddr6.sin6_family = AF_INET6;
  2687. sockaddr6.sin6_port = htons(port);
  2688. sockaddr6.sin6_addr = in6addr_loopback;
  2689. addr4 = [NSMutableData dataWithBytes:&sockaddr4 length:sizeof(sockaddr4)];
  2690. addr6 = [NSMutableData dataWithBytes:&sockaddr6 length:sizeof(sockaddr6)];
  2691. }
  2692. else
  2693. {
  2694. const char *iface = [interface UTF8String];
  2695. struct ifaddrs *addrs;
  2696. const struct ifaddrs *cursor;
  2697. if ((getifaddrs(&addrs) == 0))
  2698. {
  2699. cursor = addrs;
  2700. while (cursor != NULL)
  2701. {
  2702. if ((addr4 == nil) && (cursor->ifa_addr->sa_family == AF_INET))
  2703. {
  2704. // IPv4
  2705. struct sockaddr_in nativeAddr4;
  2706. memcpy(&nativeAddr4, cursor->ifa_addr, sizeof(nativeAddr4));
  2707. if (strcmp(cursor->ifa_name, iface) == 0)
  2708. {
  2709. // Name match
  2710. nativeAddr4.sin_port = htons(port);
  2711. addr4 = [NSMutableData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)];
  2712. }
  2713. else
  2714. {
  2715. char ip[INET_ADDRSTRLEN];
  2716. const char *conversion = inet_ntop(AF_INET, &nativeAddr4.sin_addr, ip, sizeof(ip));
  2717. if ((conversion != NULL) && (strcmp(ip, iface) == 0))
  2718. {
  2719. // IP match
  2720. nativeAddr4.sin_port = htons(port);
  2721. addr4 = [NSMutableData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)];
  2722. }
  2723. }
  2724. }
  2725. else if ((addr6 == nil) && (cursor->ifa_addr->sa_family == AF_INET6))
  2726. {
  2727. // IPv6
  2728. struct sockaddr_in6 nativeAddr6;
  2729. memcpy(&nativeAddr6, cursor->ifa_addr, sizeof(nativeAddr6));
  2730. if (strcmp(cursor->ifa_name, iface) == 0)
  2731. {
  2732. // Name match
  2733. nativeAddr6.sin6_port = htons(port);
  2734. addr6 = [NSMutableData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)];
  2735. }
  2736. else
  2737. {
  2738. char ip[INET6_ADDRSTRLEN];
  2739. const char *conversion = inet_ntop(AF_INET6, &nativeAddr6.sin6_addr, ip, sizeof(ip));
  2740. if ((conversion != NULL) && (strcmp(ip, iface) == 0))
  2741. {
  2742. // IP match
  2743. nativeAddr6.sin6_port = htons(port);
  2744. addr6 = [NSMutableData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)];
  2745. }
  2746. }
  2747. }
  2748. cursor = cursor->ifa_next;
  2749. }
  2750. freeifaddrs(addrs);
  2751. }
  2752. }
  2753. if (interfaceAddr4Ptr) *interfaceAddr4Ptr = addr4;
  2754. if (interfaceAddr6Ptr) *interfaceAddr6Ptr = addr6;
  2755. }
  2756. - (void)setupReadAndWriteSourcesForNewlyConnectedSocket:(int)socketFD
  2757. {
  2758. readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socketFD, 0, socketQueue);
  2759. writeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, socketFD, 0, socketQueue);
  2760. // Setup event handlers
  2761. dispatch_source_set_event_handler(readSource, ^{
  2762. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2763. LogVerbose(@"readEventBlock");
  2764. socketFDBytesAvailable = dispatch_source_get_data(readSource);
  2765. LogVerbose(@"socketFDBytesAvailable: %lu", socketFDBytesAvailable);
  2766. if (socketFDBytesAvailable > 0)
  2767. [self doReadData];
  2768. else
  2769. [self doReadEOF];
  2770. [pool drain];
  2771. });
  2772. dispatch_source_set_event_handler(writeSource, ^{
  2773. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2774. LogVerbose(@"writeEventBlock");
  2775. flags |= kSocketCanAcceptBytes;
  2776. [self doWriteData];
  2777. [pool drain];
  2778. });
  2779. // Setup cancel handlers
  2780. __block int socketFDRefCount = 2;
  2781. dispatch_source_t theReadSource = readSource;
  2782. dispatch_source_t theWriteSource = writeSource;
  2783. dispatch_source_set_cancel_handler(readSource, ^{
  2784. LogVerbose(@"readCancelBlock");
  2785. LogVerbose(@"dispatch_release(readSource)");
  2786. dispatch_release(theReadSource);
  2787. if (--socketFDRefCount == 0)
  2788. {
  2789. LogVerbose(@"close(socketFD)");
  2790. close(socketFD);
  2791. }
  2792. });
  2793. dispatch_source_set_cancel_handler(writeSource, ^{
  2794. LogVerbose(@"writeCancelBlock");
  2795. LogVerbose(@"dispatch_release(writeSource)");
  2796. dispatch_release(theWriteSource);
  2797. if (--socketFDRefCount == 0)
  2798. {
  2799. LogVerbose(@"close(socketFD)");
  2800. close(socketFD);
  2801. }
  2802. });
  2803. // We will not be able to read until data arrives.
  2804. // But we should be able to write immediately.
  2805. socketFDBytesAvailable = 0;
  2806. flags &= ~kReadSourceSuspended;
  2807. LogVerbose(@"dispatch_resume(readSource)");
  2808. dispatch_resume(readSource);
  2809. flags |= kSocketCanAcceptBytes;
  2810. flags |= kWriteSourceSuspended;
  2811. }
  2812. - (BOOL)usingCFStream
  2813. {
  2814. #if TARGET_OS_IPHONE
  2815. if (flags & kSocketSecure)
  2816. {
  2817. // Due to the fact that Apple doesn't give us the full power of SecureTransport on iOS,
  2818. // we are relegated to using the slower, less powerful, and RunLoop based CFStream API. :( Boo!
  2819. //
  2820. // Thus we're not able to use the GCD read/write sources in this particular scenario.
  2821. return YES;
  2822. }
  2823. #endif
  2824. return NO;
  2825. }
  2826. - (void)suspendReadSource
  2827. {
  2828. if (!(flags & kReadSourceSuspended))
  2829. {
  2830. LogVerbose(@"dispatch_suspend(readSource)");
  2831. dispatch_suspend(readSource);
  2832. flags |= kReadSourceSuspended;
  2833. }
  2834. }
  2835. - (void)resumeReadSource
  2836. {
  2837. if (flags & kReadSourceSuspended)
  2838. {
  2839. LogVerbose(@"dispatch_resume(readSource)");
  2840. dispatch_resume(readSource);
  2841. flags &= ~kReadSourceSuspended;
  2842. }
  2843. }
  2844. - (void)suspendWriteSource
  2845. {
  2846. if (!(flags & kWriteSourceSuspended))
  2847. {
  2848. LogVerbose(@"dispatch_suspend(writeSource)");
  2849. dispatch_suspend(writeSource);
  2850. flags |= kWriteSourceSuspended;
  2851. }
  2852. }
  2853. - (void)resumeWriteSource
  2854. {
  2855. if (flags & kWriteSourceSuspended)
  2856. {
  2857. LogVerbose(@"dispatch_resume(writeSource)");
  2858. dispatch_resume(writeSource);
  2859. flags &= ~kWriteSourceSuspended;
  2860. }
  2861. }
  2862. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2863. #pragma mark Reading
  2864. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2865. - (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag
  2866. {
  2867. [self readDataWithTimeout:timeout buffer:nil bufferOffset:0 maxLength:0 tag:tag];
  2868. }
  2869. - (void)readDataWithTimeout:(NSTimeInterval)timeout
  2870. buffer:(NSMutableData *)buffer
  2871. bufferOffset:(NSUInteger)offset
  2872. tag:(long)tag
  2873. {
  2874. [self readDataWithTimeout:timeout buffer:buffer bufferOffset:offset maxLength:0 tag:tag];
  2875. }
  2876. - (void)readDataWithTimeout:(NSTimeInterval)timeout
  2877. buffer:(NSMutableData *)buffer
  2878. bufferOffset:(NSUInteger)offset
  2879. maxLength:(NSUInteger)length
  2880. tag:(long)tag
  2881. {
  2882. if (offset > [buffer length]) {
  2883. LogWarn(@"Cannot read: offset > [buffer length]");
  2884. return;
  2885. }
  2886. GCDAsyncReadPacket *packet = [[GCDAsyncReadPacket alloc] initWithData:buffer
  2887. startOffset:offset
  2888. maxLength:length
  2889. timeout:timeout
  2890. readLength:0
  2891. terminator:nil
  2892. tag:tag];
  2893. dispatch_async(socketQueue, ^{
  2894. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2895. LogTrace();
  2896. if ((flags & kSocketStarted) && !(flags & kForbidReadsWrites))
  2897. {
  2898. [readQueue addObject:packet];
  2899. [self maybeDequeueRead];
  2900. }
  2901. [pool drain];
  2902. });
  2903. // Do not rely on the block being run in order to release the packet,
  2904. // as the queue might get released without the block completing.
  2905. [packet release];
  2906. }
  2907. - (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag
  2908. {
  2909. [self readDataToLength:length withTimeout:timeout buffer:nil bufferOffset:0 tag:tag];
  2910. }
  2911. - (void)readDataToLength:(NSUInteger)length
  2912. withTimeout:(NSTimeInterval)timeout
  2913. buffer:(NSMutableData *)buffer
  2914. bufferOffset:(NSUInteger)offset
  2915. tag:(long)tag
  2916. {
  2917. if (length == 0) {
  2918. LogWarn(@"Cannot read: length == 0");
  2919. return;
  2920. }
  2921. if (offset > [buffer length]) {
  2922. LogWarn(@"Cannot read: offset > [buffer length]");
  2923. return;
  2924. }
  2925. GCDAsyncReadPacket *packet = [[GCDAsyncReadPacket alloc] initWithData:buffer
  2926. startOffset:offset
  2927. maxLength:0
  2928. timeout:timeout
  2929. readLength:length
  2930. terminator:nil
  2931. tag:tag];
  2932. dispatch_async(socketQueue, ^{
  2933. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2934. LogTrace();
  2935. if ((flags & kSocketStarted) && !(flags & kForbidReadsWrites))
  2936. {
  2937. [readQueue addObject:packet];
  2938. [self maybeDequeueRead];
  2939. }
  2940. [pool drain];
  2941. });
  2942. // Do not rely on the block being run in order to release the packet,
  2943. // as the queue might get released without the block completing.
  2944. [packet release];
  2945. }
  2946. - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag
  2947. {
  2948. [self readDataToData:data withTimeout:timeout buffer:nil bufferOffset:0 maxLength:0 tag:tag];
  2949. }
  2950. - (void)readDataToData:(NSData *)data
  2951. withTimeout:(NSTimeInterval)timeout
  2952. buffer:(NSMutableData *)buffer
  2953. bufferOffset:(NSUInteger)offset
  2954. tag:(long)tag
  2955. {
  2956. [self readDataToData:data withTimeout:timeout buffer:buffer bufferOffset:offset maxLength:0 tag:tag];
  2957. }
  2958. - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(NSUInteger)length tag:(long)tag
  2959. {
  2960. [self readDataToData:data withTimeout:timeout buffer:nil bufferOffset:0 maxLength:length tag:tag];
  2961. }
  2962. - (void)readDataToData:(NSData *)data
  2963. withTimeout:(NSTimeInterval)timeout
  2964. buffer:(NSMutableData *)buffer
  2965. bufferOffset:(NSUInteger)offset
  2966. maxLength:(NSUInteger)maxLength
  2967. tag:(long)tag
  2968. {
  2969. if ([data length] == 0) {
  2970. LogWarn(@"Cannot read: [data length] == 0");
  2971. return;
  2972. }
  2973. if (offset > [buffer length]) {
  2974. LogWarn(@"Cannot read: offset > [buffer length]");
  2975. return;
  2976. }
  2977. if (maxLength > 0 && maxLength < [data length]) {
  2978. LogWarn(@"Cannot read: maxLength > 0 && maxLength < [data length]");
  2979. return;
  2980. }
  2981. GCDAsyncReadPacket *packet = [[GCDAsyncReadPacket alloc] initWithData:buffer
  2982. startOffset:offset
  2983. maxLength:maxLength
  2984. timeout:timeout
  2985. readLength:0
  2986. terminator:data
  2987. tag:tag];
  2988. dispatch_async(socketQueue, ^{
  2989. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  2990. LogTrace();
  2991. if ((flags & kSocketStarted) && !(flags & kForbidReadsWrites))
  2992. {
  2993. [readQueue addObject:packet];
  2994. [self maybeDequeueRead];
  2995. }
  2996. [pool drain];
  2997. });
  2998. // Do not rely on the block being run in order to release the packet,
  2999. // as the queue might get released without the block completing.
  3000. [packet release];
  3001. }
  3002. /**
  3003. * This method starts a new read, if needed.
  3004. *
  3005. * It is called when:
  3006. * - a user requests a read
  3007. * - after a read request has finished (to handle the next request)
  3008. * - immediately after the socket opens to handle any pending requests
  3009. *
  3010. * This method also handles auto-disconnect post read/write completion.
  3011. **/
  3012. - (void)maybeDequeueRead
  3013. {
  3014. LogTrace();
  3015. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  3016. // If we're not currently processing a read AND we have an available read stream
  3017. if ((currentRead == nil) && (flags & kConnected))
  3018. {
  3019. if ([readQueue count] > 0)
  3020. {
  3021. // Dequeue the next object in the write queue
  3022. currentRead = [[readQueue objectAtIndex:0] retain];
  3023. [readQueue removeObjectAtIndex:0];
  3024. if ([currentRead isKindOfClass:[GCDAsyncSpecialPacket class]])
  3025. {
  3026. LogVerbose(@"Dequeued GCDAsyncSpecialPacket");
  3027. // Attempt to start TLS
  3028. flags |= kStartingReadTLS;
  3029. // This method won't do anything unless both kStartingReadTLS and kStartingWriteTLS are set
  3030. [self maybeStartTLS];
  3031. }
  3032. else
  3033. {
  3034. LogVerbose(@"Dequeued GCDAsyncReadPacket");
  3035. // Setup read timer (if needed)
  3036. [self setupReadTimerWithTimeout:currentRead->timeout];
  3037. // Immediately read, if possible
  3038. [self doReadData];
  3039. }
  3040. }
  3041. else if (flags & kDisconnectAfterReads)
  3042. {
  3043. if (flags & kDisconnectAfterWrites)
  3044. {
  3045. if (([writeQueue count] == 0) && (currentWrite == nil))
  3046. {
  3047. [self closeWithError:nil];
  3048. }
  3049. }
  3050. else
  3051. {
  3052. [self closeWithError:nil];
  3053. }
  3054. }
  3055. else if (flags & kSocketSecure)
  3056. {
  3057. [self flushSSLBuffers];
  3058. // Edge case:
  3059. //
  3060. // We just drained all data from the ssl buffers,
  3061. // and all known data from the socket (socketFDBytesAvailable).
  3062. //
  3063. // If we didn't get any data from this process,
  3064. // then we may have reached the end of the TCP stream.
  3065. //
  3066. // Be sure callbacks are enabled so we're notified about a disconnection.
  3067. if ([partialReadBuffer length] == 0)
  3068. {
  3069. if ([self usingCFStream]) {
  3070. // Callbacks never disabled
  3071. }
  3072. else {
  3073. [self resumeReadSource];
  3074. }
  3075. }
  3076. }
  3077. }
  3078. }
  3079. - (void)flushSSLBuffers
  3080. {
  3081. LogTrace();
  3082. NSAssert((flags & kSocketSecure), @"Cannot flush ssl buffers on non-secure socket");
  3083. if ([partialReadBuffer length] > 0)
  3084. {
  3085. // Only flush the ssl buffers if the partialReadBuffer is empty.
  3086. // This is to avoid growing the partialReadBuffer inifinitely large.
  3087. return;
  3088. }
  3089. #if TARGET_OS_IPHONE
  3090. if ((flags & kSecureSocketHasBytesAvailable) && CFReadStreamHasBytesAvailable(readStream))
  3091. {
  3092. LogVerbose(@"%@ - Flushing ssl buffers into partialReadBuffer...", THIS_METHOD);
  3093. CFIndex defaultBytesToRead = (1024 * 16);
  3094. NSUInteger partialReadBufferOffset = [partialReadBuffer length];
  3095. [partialReadBuffer increaseLengthBy:defaultBytesToRead];
  3096. uint8_t *buffer = [partialReadBuffer mutableBytes] + partialReadBufferOffset;
  3097. CFIndex result = CFReadStreamRead(readStream, buffer, defaultBytesToRead);
  3098. LogVerbose(@"%@ - CFReadStreamRead(): result = %i", THIS_METHOD, (int)result);
  3099. if (result <= 0)
  3100. {
  3101. [partialReadBuffer setLength:partialReadBufferOffset];
  3102. }
  3103. else
  3104. {
  3105. [partialReadBuffer setLength:(partialReadBufferOffset + result)];
  3106. }
  3107. flags &= ~kSecureSocketHasBytesAvailable;
  3108. }
  3109. #else
  3110. __block NSUInteger estimatedBytesAvailable = 0;
  3111. dispatch_block_t updateEstimatedBytesAvailable = ^{
  3112. // Figure out if there is any data available to be read
  3113. //
  3114. // socketFDBytesAvailable <- Number of encrypted bytes we haven't read from the bsd socket
  3115. // [sslReadBuffer length] <- Number of encrypted bytes we've buffered from bsd socket
  3116. // sslInternalBufSize <- Number od decrypted bytes SecureTransport has buffered
  3117. //
  3118. // We call the variable "estimated" because we don't know how many decrypted bytes we'll get
  3119. // from the encrypted bytes in the sslReadBuffer.
  3120. // However, we do know this is an upper bound on the estimation.
  3121. estimatedBytesAvailable = socketFDBytesAvailable + [sslReadBuffer length];
  3122. size_t sslInternalBufSize = 0;
  3123. SSLGetBufferedReadSize(sslContext, &sslInternalBufSize);
  3124. estimatedBytesAvailable += sslInternalBufSize;
  3125. };
  3126. updateEstimatedBytesAvailable();
  3127. if (estimatedBytesAvailable > 0)
  3128. {
  3129. LogVerbose(@"%@ - Flushing ssl buffers into partialReadBuffer...", THIS_METHOD);
  3130. BOOL done = NO;
  3131. do
  3132. {
  3133. LogVerbose(@"%@ - estimatedBytesAvailable = %lu", THIS_METHOD, (unsigned long)estimatedBytesAvailable);
  3134. // Make room in the partialReadBuffer
  3135. NSUInteger partialReadBufferOffset = [partialReadBuffer length];
  3136. [partialReadBuffer increaseLengthBy:estimatedBytesAvailable];
  3137. uint8_t *buffer = (uint8_t *)[partialReadBuffer mutableBytes] + partialReadBufferOffset;
  3138. size_t bytesRead = 0;
  3139. // Read data into partialReadBuffer
  3140. OSStatus result = SSLRead(sslContext, buffer, (size_t)estimatedBytesAvailable, &bytesRead);
  3141. LogVerbose(@"%@ - read from secure socket = %u", THIS_METHOD, (unsigned)bytesRead);
  3142. [partialReadBuffer setLength:(partialReadBufferOffset + bytesRead)];
  3143. LogVerbose(@"%@ - partialReadBuffer.length = %lu", THIS_METHOD, (unsigned long)[partialReadBuffer length]);
  3144. if (result != noErr)
  3145. {
  3146. done = YES;
  3147. }
  3148. else
  3149. {
  3150. updateEstimatedBytesAvailable();
  3151. }
  3152. } while (!done && estimatedBytesAvailable > 0);
  3153. }
  3154. #endif
  3155. }
  3156. - (void)doReadData
  3157. {
  3158. LogTrace();
  3159. // This method is called on the socketQueue.
  3160. // It might be called directly, or via the readSource when data is available to be read.
  3161. if ((currentRead == nil) || (flags & kReadsPaused))
  3162. {
  3163. LogVerbose(@"No currentRead or kReadsPaused");
  3164. // Unable to read at this time
  3165. if (flags & kSocketSecure)
  3166. {
  3167. // Here's the situation:
  3168. //
  3169. // We have an established secure connection.
  3170. // There may not be a currentRead, but there might be encrypted data sitting around for us.
  3171. // When the user does get around to issuing a read, that encrypted data will need to be decrypted.
  3172. //
  3173. // So why make the user wait?
  3174. // We might as well get a head start on decrypting some data now.
  3175. //
  3176. // The other reason we do this has to do with detecting a socket disconnection.
  3177. // The SSL/TLS protocol has it's own disconnection handshake.
  3178. // So when a secure socket is closed, a "goodbye" packet comes across the wire.
  3179. // We want to make sure we read the "goodbye" packet so we can properly detect the TCP disconnection.
  3180. [self flushSSLBuffers];
  3181. }
  3182. if ([self usingCFStream])
  3183. {
  3184. // CFReadStream only fires once when there is available data.
  3185. // It won't fire again until we've invoked CFReadStreamRead.
  3186. }
  3187. else
  3188. {
  3189. // If the readSource is firing, we need to pause it
  3190. // or else it will continue to fire over and over again.
  3191. //
  3192. // If the readSource is not firing,
  3193. // we want it to continue monitoring the socket.
  3194. if (socketFDBytesAvailable > 0)
  3195. {
  3196. [self suspendReadSource];
  3197. }
  3198. }
  3199. return;
  3200. }
  3201. BOOL hasBytesAvailable;
  3202. unsigned long estimatedBytesAvailable;
  3203. #if TARGET_OS_IPHONE
  3204. {
  3205. if (flags & kSocketSecure)
  3206. {
  3207. // Relegated to using CFStream... :( Boo! Give us SecureTransport Apple!
  3208. estimatedBytesAvailable = 0;
  3209. if ((flags & kSecureSocketHasBytesAvailable) && CFReadStreamHasBytesAvailable(readStream))
  3210. hasBytesAvailable = YES;
  3211. else
  3212. hasBytesAvailable = NO;
  3213. }
  3214. else
  3215. {
  3216. estimatedBytesAvailable = socketFDBytesAvailable;
  3217. hasBytesAvailable = (estimatedBytesAvailable > 0);
  3218. }
  3219. }
  3220. #else
  3221. {
  3222. estimatedBytesAvailable = socketFDBytesAvailable;
  3223. if (flags & kSocketSecure)
  3224. {
  3225. // There are 2 buffers to be aware of here.
  3226. //
  3227. // We are using SecureTransport, a TLS/SSL security layer which sits atop TCP.
  3228. // We issue a read to the SecureTranport API, which in turn issues a read to our SSLReadFunction.
  3229. // Our SSLReadFunction then reads from the BSD socket and returns the encrypted data to SecureTransport.
  3230. // SecureTransport then decrypts the data, and finally returns the decrypted data back to us.
  3231. //
  3232. // The first buffer is one we create.
  3233. // SecureTransport often requests small amounts of data.
  3234. // This has to do with the encypted packets that are coming across the TCP stream.
  3235. // But it's non-optimal to do a bunch of small reads from the BSD socket.
  3236. // So our SSLReadFunction reads all available data from the socket (optimizing the sys call)
  3237. // and may store excess in the sslReadBuffer.
  3238. estimatedBytesAvailable += [sslReadBuffer length];
  3239. // The second buffer is within SecureTransport.
  3240. // As mentioned earlier, there are encrypted packets coming across the TCP stream.
  3241. // SecureTransport needs the entire packet to decrypt it.
  3242. // But if the entire packet produces X bytes of decrypted data,
  3243. // and we only asked SecureTransport for X/2 bytes of data,
  3244. // it must store the extra X/2 bytes of decrypted data for the next read.
  3245. //
  3246. // The SSLGetBufferedReadSize function will tell us the size of this internal buffer.
  3247. // From the documentation:
  3248. //
  3249. // "This function does not block or cause any low-level read operations to occur."
  3250. size_t sslInternalBufSize = 0;
  3251. SSLGetBufferedReadSize(sslContext, &sslInternalBufSize);
  3252. estimatedBytesAvailable += sslInternalBufSize;
  3253. }
  3254. hasBytesAvailable = (estimatedBytesAvailable > 0);
  3255. }
  3256. #endif
  3257. if ((hasBytesAvailable == NO) && ([partialReadBuffer length] == 0))
  3258. {
  3259. LogVerbose(@"No data available to read...");
  3260. // No data available to read.
  3261. if (![self usingCFStream])
  3262. {
  3263. // Need to wait for readSource to fire and notify us of
  3264. // available data in the socket's internal read buffer.
  3265. [self resumeReadSource];
  3266. }
  3267. return;
  3268. }
  3269. if (flags & kStartingReadTLS)
  3270. {
  3271. LogVerbose(@"Waiting for SSL/TLS handshake to complete");
  3272. // The readQueue is waiting for SSL/TLS handshake to complete.
  3273. if (flags & kStartingWriteTLS)
  3274. {
  3275. #if !TARGET_OS_IPHONE
  3276. {
  3277. // We are in the process of a SSL Handshake.
  3278. // We were waiting for incoming data which has just arrived.
  3279. [self continueSSLHandshake];
  3280. }
  3281. #endif
  3282. }
  3283. else
  3284. {
  3285. // We are still waiting for the writeQueue to drain and start the SSL/TLS process.
  3286. // We now know data is available to read.
  3287. if (![self usingCFStream])
  3288. {
  3289. // Suspend the read source or else it will continue to fire nonstop.
  3290. [self suspendReadSource];
  3291. }
  3292. }
  3293. return;
  3294. }
  3295. BOOL done = NO; // Completed read operation
  3296. NSError *error = nil; // Error occured
  3297. NSUInteger totalBytesReadForCurrentRead = 0;
  3298. //
  3299. // STEP 1 - READ FROM PREBUFFER
  3300. //
  3301. NSUInteger partialReadBufferLength = [partialReadBuffer length];
  3302. if (partialReadBufferLength > 0)
  3303. {
  3304. // There are 3 types of read packets:
  3305. //
  3306. // 1) Read all available data.
  3307. // 2) Read a specific length of data.
  3308. // 3) Read up to a particular terminator.
  3309. NSUInteger bytesToCopy;
  3310. if (currentRead->term != nil)
  3311. {
  3312. // Read type #3 - read up to a terminator
  3313. bytesToCopy = [currentRead readLengthForTermWithPreBuffer:partialReadBuffer found:&done];
  3314. }
  3315. else
  3316. {
  3317. // Read type #1 or #2
  3318. bytesToCopy = [currentRead readLengthForNonTermWithHint:partialReadBufferLength];
  3319. }
  3320. // Make sure we have enough room in the buffer for our read.
  3321. [currentRead ensureCapacityForAdditionalDataOfLength:bytesToCopy];
  3322. // Copy bytes from prebuffer into packet buffer
  3323. uint8_t *buffer = (uint8_t *)[currentRead->buffer mutableBytes] + currentRead->startOffset +
  3324. currentRead->bytesDone;
  3325. memcpy(buffer, [partialReadBuffer bytes], bytesToCopy);
  3326. // Remove the copied bytes from the partial read buffer
  3327. [partialReadBuffer replaceBytesInRange:NSMakeRange(0, bytesToCopy) withBytes:NULL length:0];
  3328. partialReadBufferLength -= bytesToCopy;
  3329. LogVerbose(@"copied(%lu) partialReadBufferLength(%lu)", bytesToCopy, partialReadBufferLength);
  3330. // Update totals
  3331. currentRead->bytesDone += bytesToCopy;
  3332. totalBytesReadForCurrentRead += bytesToCopy;
  3333. // Check to see if the read operation is done
  3334. if (currentRead->readLength > 0)
  3335. {
  3336. // Read type #2 - read a specific length of data
  3337. done = (currentRead->bytesDone == currentRead->readLength);
  3338. }
  3339. else if (currentRead->term != nil)
  3340. {
  3341. // Read type #3 - read up to a terminator
  3342. // Our 'done' variable was updated via the readLengthForTermWithPreBuffer:found: method
  3343. if (!done && currentRead->maxLength > 0)
  3344. {
  3345. // We're not done and there's a set maxLength.
  3346. // Have we reached that maxLength yet?
  3347. if (currentRead->bytesDone >= currentRead->maxLength)
  3348. {
  3349. error = [self readMaxedOutError];
  3350. }
  3351. }
  3352. }
  3353. else
  3354. {
  3355. // Read type #1 - read all available data
  3356. //
  3357. // We're done as soon as
  3358. // - we've read all available data (in prebuffer and socket)
  3359. // - we've read the maxLength of read packet.
  3360. done = ((currentRead->maxLength > 0) && (currentRead->bytesDone == currentRead->maxLength));
  3361. }
  3362. }
  3363. //
  3364. // STEP 2 - READ FROM SOCKET
  3365. //
  3366. BOOL socketEOF = (flags & kSocketHasReadEOF) ? YES : NO; // Nothing more to via socket (end of file)
  3367. BOOL waiting = !done && !error && !socketEOF && !hasBytesAvailable; // Ran out of data, waiting for more
  3368. if (!done && !error && !socketEOF && !waiting && hasBytesAvailable)
  3369. {
  3370. NSAssert((partialReadBufferLength == 0), @"Invalid logic");
  3371. // There are 3 types of read packets:
  3372. //
  3373. // 1) Read all available data.
  3374. // 2) Read a specific length of data.
  3375. // 3) Read up to a particular terminator.
  3376. BOOL readIntoPartialReadBuffer = NO;
  3377. NSUInteger bytesToRead;
  3378. if ([self usingCFStream])
  3379. {
  3380. // Since Apple has neglected to make SecureTransport available on iOS,
  3381. // we are relegated to using the slower, less powerful, RunLoop based CFStream API.
  3382. //
  3383. // This API doesn't tell us how much data is available on the socket to be read.
  3384. // If we had that information we could optimize our memory allocations, and sys calls.
  3385. //
  3386. // But alas...
  3387. // So we do it old school, and just read as much data from the socket as we can.
  3388. NSUInteger defaultReadLength = (1024 * 32);
  3389. bytesToRead = [currentRead optimalReadLengthWithDefault:defaultReadLength
  3390. shouldPreBuffer:&readIntoPartialReadBuffer];
  3391. }
  3392. else
  3393. {
  3394. if (currentRead->term != nil)
  3395. {
  3396. // Read type #3 - read up to a terminator
  3397. bytesToRead = [currentRead readLengthForTermWithHint:estimatedBytesAvailable
  3398. shouldPreBuffer:&readIntoPartialReadBuffer];
  3399. }
  3400. else
  3401. {
  3402. // Read type #1 or #2
  3403. bytesToRead = [currentRead readLengthForNonTermWithHint:estimatedBytesAvailable];
  3404. }
  3405. }
  3406. if (bytesToRead > SIZE_MAX) // NSUInteger may be bigger than size_t (read param 3)
  3407. {
  3408. bytesToRead = SIZE_MAX;
  3409. }
  3410. // Make sure we have enough room in the buffer for our read.
  3411. //
  3412. // We are either reading directly into the currentRead->buffer,
  3413. // or we're reading into the temporary partialReadBuffer.
  3414. uint8_t *buffer;
  3415. if (readIntoPartialReadBuffer)
  3416. {
  3417. if (bytesToRead > partialReadBufferLength)
  3418. {
  3419. [partialReadBuffer setLength:bytesToRead];
  3420. }
  3421. buffer = [partialReadBuffer mutableBytes];
  3422. }
  3423. else
  3424. {
  3425. [currentRead ensureCapacityForAdditionalDataOfLength:bytesToRead];
  3426. buffer = (uint8_t *)[currentRead->buffer mutableBytes] + currentRead->startOffset + currentRead->bytesDone;
  3427. }
  3428. // Read data into buffer
  3429. size_t bytesRead = 0;
  3430. if (flags & kSocketSecure)
  3431. {
  3432. #if TARGET_OS_IPHONE
  3433. {
  3434. CFIndex result = CFReadStreamRead(readStream, buffer, (CFIndex)bytesToRead);
  3435. LogVerbose(@"CFReadStreamRead(): result = %i", (int)result);
  3436. if (result < 0)
  3437. {
  3438. error = [NSMakeCollectable(CFReadStreamCopyError(readStream)) autorelease];
  3439. if (readIntoPartialReadBuffer)
  3440. [partialReadBuffer setLength:0];
  3441. }
  3442. else if (result == 0)
  3443. {
  3444. socketEOF = YES;
  3445. if (readIntoPartialReadBuffer)
  3446. [partialReadBuffer setLength:0];
  3447. }
  3448. else
  3449. {
  3450. waiting = YES;
  3451. bytesRead = (size_t)result;
  3452. }
  3453. // We only know how many decrypted bytes were read.
  3454. // The actual number of bytes read was likely more due to the overhead of the encryption.
  3455. // So we reset our flag, and rely on the next callback to alert us of more data.
  3456. flags &= ~kSecureSocketHasBytesAvailable;
  3457. }
  3458. #else
  3459. {
  3460. // The documentation from Apple states:
  3461. //
  3462. // "a read operation might return errSSLWouldBlock,
  3463. // indicating that less data than requested was actually transferred"
  3464. //
  3465. // However, starting around 10.7, the function will sometimes return noErr,
  3466. // even if it didn't read as much data as requested. So we need to watch out for that.
  3467. OSStatus result;
  3468. do
  3469. {
  3470. void *loop_buffer = buffer + bytesRead;
  3471. size_t loop_bytesToRead = (size_t)bytesToRead - bytesRead;
  3472. size_t loop_bytesRead = 0;
  3473. result = SSLRead(sslContext, loop_buffer, loop_bytesToRead, &loop_bytesRead);
  3474. LogVerbose(@"read from secure socket = %u", (unsigned)bytesRead);
  3475. bytesRead += loop_bytesRead;
  3476. } while ((result == noErr) && (bytesRead < bytesToRead));
  3477. if (result != noErr)
  3478. {
  3479. if (result == errSSLWouldBlock)
  3480. waiting = YES;
  3481. else
  3482. error = [self sslError:result];
  3483. // It's possible that bytesRead > 0, yet the result is errSSLWouldBlock.
  3484. // This happens when the SSLRead function is able to read some data,
  3485. // but not the entire amount we requested.
  3486. if (bytesRead <= 0)
  3487. {
  3488. bytesRead = 0;
  3489. if (readIntoPartialReadBuffer)
  3490. [partialReadBuffer setLength:0];
  3491. }
  3492. }
  3493. // Do not modify socketFDBytesAvailable.
  3494. // It will be updated via the SSLReadFunction().
  3495. }
  3496. #endif
  3497. }
  3498. else
  3499. {
  3500. int socketFD = (socket4FD == SOCKET_NULL) ? socket6FD : socket4FD;
  3501. ssize_t result = read(socketFD, buffer, (size_t)bytesToRead);
  3502. LogVerbose(@"read from socket = %i", (int)result);
  3503. if (result < 0)
  3504. {
  3505. if (errno == EWOULDBLOCK)
  3506. waiting = YES;
  3507. else
  3508. error = [self errnoErrorWithReason:@"Error in read() function"];
  3509. socketFDBytesAvailable = 0;
  3510. if (readIntoPartialReadBuffer)
  3511. [partialReadBuffer setLength:0];
  3512. }
  3513. else if (result == 0)
  3514. {
  3515. socketEOF = YES;
  3516. socketFDBytesAvailable = 0;
  3517. if (readIntoPartialReadBuffer)
  3518. [partialReadBuffer setLength:0];
  3519. }
  3520. else
  3521. {
  3522. bytesRead = result;
  3523. if (socketFDBytesAvailable <= bytesRead)
  3524. socketFDBytesAvailable = 0;
  3525. else
  3526. socketFDBytesAvailable -= bytesRead;
  3527. if (socketFDBytesAvailable == 0)
  3528. {
  3529. waiting = YES;
  3530. }
  3531. }
  3532. }
  3533. if (bytesRead > 0)
  3534. {
  3535. // Check to see if the read operation is done
  3536. if (currentRead->readLength > 0)
  3537. {
  3538. // Read type #2 - read a specific length of data
  3539. //
  3540. // Note: We should never be using a prebuffer when we're reading a specific length of data.
  3541. NSAssert(readIntoPartialReadBuffer == NO, @"Invalid logic");
  3542. currentRead->bytesDone += bytesRead;
  3543. totalBytesReadForCurrentRead += bytesRead;
  3544. done = (currentRead->bytesDone == currentRead->readLength);
  3545. }
  3546. else if (currentRead->term != nil)
  3547. {
  3548. // Read type #3 - read up to a terminator
  3549. if (readIntoPartialReadBuffer)
  3550. {
  3551. // We just read a big chunk of data into the partialReadBuffer.
  3552. // Search for the terminating sequence.
  3553. //
  3554. // Note: We are depending upon [partialReadBuffer length] to tell us how much data is
  3555. // available in the partialReadBuffer. So we need to be sure this matches how many bytes
  3556. // have actually been read into said buffer.
  3557. [partialReadBuffer setLength:bytesRead];
  3558. bytesToRead = [currentRead readLengthForTermWithPreBuffer:partialReadBuffer found:&done];
  3559. // Ensure there's room on the read packet's buffer
  3560. [currentRead ensureCapacityForAdditionalDataOfLength:bytesToRead];
  3561. // Copy bytes from prebuffer into read buffer
  3562. uint8_t *preBuf = [partialReadBuffer mutableBytes];
  3563. uint8_t *readBuf = (uint8_t *)[currentRead->buffer mutableBytes] + currentRead->startOffset
  3564. + currentRead->bytesDone;
  3565. memcpy(readBuf, preBuf, bytesToRead);
  3566. // Remove the copied bytes from the prebuffer
  3567. [partialReadBuffer replaceBytesInRange:NSMakeRange(0, bytesToRead) withBytes:NULL length:0];
  3568. // Update totals
  3569. currentRead->bytesDone += bytesToRead;
  3570. totalBytesReadForCurrentRead += bytesToRead;
  3571. // Our 'done' variable was updated via the readLengthForTermWithPreBuffer:found: method above
  3572. }
  3573. else
  3574. {
  3575. // We just read a big chunk of data directly into the packet's buffer.
  3576. // We need to move any overflow into the prebuffer.
  3577. NSInteger overflow = [currentRead searchForTermAfterPreBuffering:bytesRead];
  3578. if (overflow == 0)
  3579. {
  3580. // Perfect match!
  3581. // Every byte we read stays in the read buffer,
  3582. // and the last byte we read was the last byte of the term.
  3583. currentRead->bytesDone += bytesRead;
  3584. totalBytesReadForCurrentRead += bytesRead;
  3585. done = YES;
  3586. }
  3587. else if (overflow > 0)
  3588. {
  3589. // The term was found within the data that we read,
  3590. // and there are extra bytes that extend past the end of the term.
  3591. // We need to move these excess bytes out of the read packet and into the prebuffer.
  3592. NSInteger underflow = bytesRead - overflow;
  3593. // Copy excess data into partialReadBuffer
  3594. void *overflowBuffer = buffer + currentRead->bytesDone + underflow;
  3595. [partialReadBuffer appendBytes:overflowBuffer length:overflow];
  3596. // Note: The completeCurrentRead method will trim the buffer for us.
  3597. currentRead->bytesDone += underflow;
  3598. totalBytesReadForCurrentRead += underflow;
  3599. done = YES;
  3600. }
  3601. else
  3602. {
  3603. // The term was not found within the data that we read.
  3604. currentRead->bytesDone += bytesRead;
  3605. totalBytesReadForCurrentRead += bytesRead;
  3606. done = NO;
  3607. }
  3608. }
  3609. if (!done && currentRead->maxLength > 0)
  3610. {
  3611. // We're not done and there's a set maxLength.
  3612. // Have we reached that maxLength yet?
  3613. if (currentRead->bytesDone >= currentRead->maxLength)
  3614. {
  3615. error = [self readMaxedOutError];
  3616. }
  3617. }
  3618. }
  3619. else
  3620. {
  3621. // Read type #1 - read all available data
  3622. if (readIntoPartialReadBuffer)
  3623. {
  3624. // We just read a chunk of data into the partialReadBuffer.
  3625. // Copy the data into the read packet.
  3626. //
  3627. // Recall that we didn't read directly into the packet's buffer to avoid
  3628. // over-allocating memory since we had no clue how much data was available to be read.
  3629. //
  3630. // Note: We are depending upon [partialReadBuffer length] to tell us how much data is
  3631. // available in the partialReadBuffer. So we need to be sure this matches how many bytes
  3632. // have actually been read into said buffer.
  3633. [partialReadBuffer setLength:bytesRead];
  3634. // Ensure there's room on the read packet's buffer
  3635. [currentRead ensureCapacityForAdditionalDataOfLength:bytesRead];
  3636. // Copy bytes from prebuffer into read buffer
  3637. uint8_t *preBuf = [partialReadBuffer mutableBytes];
  3638. uint8_t *readBuf = (uint8_t *)[currentRead->buffer mutableBytes] + currentRead->startOffset
  3639. + currentRead->bytesDone;
  3640. memcpy(readBuf, preBuf, bytesRead);
  3641. // Remove the copied bytes from the prebuffer
  3642. [partialReadBuffer replaceBytesInRange:NSMakeRange(0, bytesRead) withBytes:NULL length:0];
  3643. // Update totals
  3644. currentRead->bytesDone += bytesRead;
  3645. totalBytesReadForCurrentRead += bytesRead;
  3646. }
  3647. else
  3648. {
  3649. currentRead->bytesDone += bytesRead;
  3650. totalBytesReadForCurrentRead += bytesRead;
  3651. }
  3652. done = YES;
  3653. }
  3654. } // if (bytesRead > 0)
  3655. } // if (!done && !error && !socketEOF && !waiting && hasBytesAvailable)
  3656. if (!done && currentRead->readLength == 0 && currentRead->term == nil)
  3657. {
  3658. // Read type #1 - read all available data
  3659. //
  3660. // We might arrive here if we read data from the prebuffer but not from the socket.
  3661. done = (totalBytesReadForCurrentRead > 0);
  3662. }
  3663. // Check to see if we're done, or if we've made progress
  3664. if (done)
  3665. {
  3666. [self completeCurrentRead];
  3667. if (!error && (!socketEOF || partialReadBufferLength > 0))
  3668. {
  3669. [self maybeDequeueRead];
  3670. }
  3671. }
  3672. else if (totalBytesReadForCurrentRead > 0)
  3673. {
  3674. // We're not done read type #2 or #3 yet, but we have read in some bytes
  3675. if (delegateQueue && [delegate respondsToSelector:@selector(socket:didReadPartialDataOfLength:tag:)])
  3676. {
  3677. id theDelegate = delegate;
  3678. GCDAsyncReadPacket *theRead = currentRead;
  3679. dispatch_async(delegateQueue, ^{
  3680. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  3681. [theDelegate socket:self didReadPartialDataOfLength:totalBytesReadForCurrentRead tag:theRead->tag];
  3682. [pool drain];
  3683. });
  3684. }
  3685. }
  3686. // Check for errors
  3687. if (error)
  3688. {
  3689. [self closeWithError:error];
  3690. }
  3691. else if (socketEOF)
  3692. {
  3693. [self doReadEOF];
  3694. }
  3695. else if (waiting)
  3696. {
  3697. if (![self usingCFStream])
  3698. {
  3699. // Monitor the socket for readability (if we're not already doing so)
  3700. [self resumeReadSource];
  3701. }
  3702. }
  3703. // Do not add any code here without first adding return statements in the error cases above.
  3704. }
  3705. - (void)doReadEOF
  3706. {
  3707. LogTrace();
  3708. // This method may be called more than once.
  3709. // If the EOF is read while there is still data in the partialReadBuffer,
  3710. // then this method may be called continually after invocations of doReadData to see if it's time to disconnect.
  3711. flags |= kSocketHasReadEOF;
  3712. if (flags & kSocketSecure)
  3713. {
  3714. // If the SSL layer has any buffered data, flush it into the partialReadBuffer now.
  3715. [self flushSSLBuffers];
  3716. }
  3717. BOOL shouldDisconnect;
  3718. NSError *error = nil;
  3719. if ((flags & kStartingReadTLS) || (flags & kStartingWriteTLS))
  3720. {
  3721. // We received an EOF during or prior to startTLS.
  3722. // The SSL/TLS handshake is now impossible, so this is an unrecoverable situation.
  3723. shouldDisconnect = YES;
  3724. #if !TARGET_OS_IPHONE
  3725. error = [self sslError:errSSLClosedAbort];
  3726. #endif
  3727. }
  3728. else if (flags & kReadStreamClosed)
  3729. {
  3730. // The partialReadBuffer has already been drained.
  3731. // The config allows half-duplex connections.
  3732. // We've previously checked the socket, and it appeared writeable.
  3733. // So we marked the read stream as closed and notified the delegate.
  3734. //
  3735. // As per the half-duplex contract, the socket will be closed when a write fails,
  3736. // or when the socket is manually closed.
  3737. shouldDisconnect = NO;
  3738. }
  3739. else if ([partialReadBuffer length] > 0)
  3740. {
  3741. LogVerbose(@"Socket reached EOF, but there is still data available in prebuffer");
  3742. // Although we won't be able to read any more data from the socket,
  3743. // there is existing data that has been prebuffered that we can read.
  3744. shouldDisconnect = NO;
  3745. }
  3746. else if (config & kAllowHalfDuplexConnection)
  3747. {
  3748. // We just received an EOF (end of file) from the socket's read stream.
  3749. // This means the remote end of the socket (the peer we're connected to)
  3750. // has explicitly stated that it will not be sending us any more data.
  3751. //
  3752. // Query the socket to see if it is still writeable. (Perhaps the peer will continue reading data from us)
  3753. int socketFD = (socket4FD == SOCKET_NULL) ? socket6FD : socket4FD;
  3754. struct pollfd pfd[1];
  3755. pfd[0].fd = socketFD;
  3756. pfd[0].events = POLLOUT;
  3757. pfd[0].revents = 0;
  3758. poll(pfd, 1, 0);
  3759. if (pfd[0].revents & POLLOUT)
  3760. {
  3761. // Socket appears to still be writeable
  3762. shouldDisconnect = NO;
  3763. flags |= kReadStreamClosed;
  3764. // Notify the delegate that we're going half-duplex
  3765. if (delegateQueue && [delegate respondsToSelector:@selector(socketDidCloseReadStream:)])
  3766. {
  3767. id theDelegate = delegate;
  3768. dispatch_async(delegateQueue, ^{
  3769. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  3770. [theDelegate socketDidCloseReadStream:self];
  3771. [pool drain];
  3772. });
  3773. }
  3774. }
  3775. else
  3776. {
  3777. shouldDisconnect = YES;
  3778. }
  3779. }
  3780. else
  3781. {
  3782. shouldDisconnect = YES;
  3783. }
  3784. if (shouldDisconnect)
  3785. {
  3786. if (error == nil)
  3787. {
  3788. error = [self connectionClosedError];
  3789. }
  3790. [self closeWithError:error];
  3791. }
  3792. else
  3793. {
  3794. if (![self usingCFStream])
  3795. {
  3796. // Suspend the read source (if needed)
  3797. [self suspendReadSource];
  3798. }
  3799. }
  3800. }
  3801. - (void)completeCurrentRead
  3802. {
  3803. LogTrace();
  3804. NSAssert(currentRead, @"Trying to complete current read when there is no current read.");
  3805. NSData *result;
  3806. if (currentRead->bufferOwner)
  3807. {
  3808. // We created the buffer on behalf of the user.
  3809. // Trim our buffer to be the proper size.
  3810. [currentRead->buffer setLength:currentRead->bytesDone];
  3811. result = currentRead->buffer;
  3812. }
  3813. else
  3814. {
  3815. // We did NOT create the buffer.
  3816. // The buffer is owned by the caller.
  3817. // Only trim the buffer if we had to increase its size.
  3818. if ([currentRead->buffer length] > currentRead->originalBufferLength)
  3819. {
  3820. NSUInteger readSize = currentRead->startOffset + currentRead->bytesDone;
  3821. NSUInteger origSize = currentRead->originalBufferLength;
  3822. NSUInteger buffSize = MAX(readSize, origSize);
  3823. [currentRead->buffer setLength:buffSize];
  3824. }
  3825. uint8_t *buffer = (uint8_t *)[currentRead->buffer mutableBytes] + currentRead->startOffset;
  3826. result = [NSData dataWithBytesNoCopy:buffer length:currentRead->bytesDone freeWhenDone:NO];
  3827. }
  3828. if (delegateQueue && [delegate respondsToSelector:@selector(socket:didReadData:withTag:)])
  3829. {
  3830. id theDelegate = delegate;
  3831. GCDAsyncReadPacket *theRead = currentRead;
  3832. dispatch_async(delegateQueue, ^{
  3833. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  3834. [theDelegate socket:self didReadData:result withTag:theRead->tag];
  3835. [pool drain];
  3836. });
  3837. }
  3838. [self endCurrentRead];
  3839. }
  3840. - (void)endCurrentRead
  3841. {
  3842. if (readTimer)
  3843. {
  3844. dispatch_source_cancel(readTimer);
  3845. readTimer = NULL;
  3846. }
  3847. [currentRead release];
  3848. currentRead = nil;
  3849. }
  3850. - (void)setupReadTimerWithTimeout:(NSTimeInterval)timeout
  3851. {
  3852. if (timeout >= 0.0)
  3853. {
  3854. readTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, socketQueue);
  3855. dispatch_source_set_event_handler(readTimer, ^{
  3856. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  3857. [self doReadTimeout];
  3858. [pool drain];
  3859. });
  3860. dispatch_source_t theReadTimer = readTimer;
  3861. dispatch_source_set_cancel_handler(readTimer, ^{
  3862. LogVerbose(@"dispatch_release(readTimer)");
  3863. dispatch_release(theReadTimer);
  3864. });
  3865. dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (timeout * NSEC_PER_SEC));
  3866. dispatch_source_set_timer(readTimer, tt, DISPATCH_TIME_FOREVER, 0);
  3867. dispatch_resume(readTimer);
  3868. }
  3869. }
  3870. - (void)doReadTimeout
  3871. {
  3872. // This is a little bit tricky.
  3873. // Ideally we'd like to synchronously query the delegate about a timeout extension.
  3874. // But if we do so synchronously we risk a possible deadlock.
  3875. // So instead we have to do so asynchronously, and callback to ourselves from within the delegate block.
  3876. flags |= kReadsPaused;
  3877. if (delegateQueue && [delegate respondsToSelector:@selector(socket:shouldTimeoutReadWithTag:elapsed:bytesDone:)])
  3878. {
  3879. id theDelegate = delegate;
  3880. GCDAsyncReadPacket *theRead = currentRead;
  3881. dispatch_async(delegateQueue, ^{
  3882. NSAutoreleasePool *delegatePool = [[NSAutoreleasePool alloc] init];
  3883. NSTimeInterval timeoutExtension = 0.0;
  3884. timeoutExtension = [theDelegate socket:self shouldTimeoutReadWithTag:theRead->tag
  3885. elapsed:theRead->timeout
  3886. bytesDone:theRead->bytesDone];
  3887. dispatch_async(socketQueue, ^{
  3888. NSAutoreleasePool *callbackPool = [[NSAutoreleasePool alloc] init];
  3889. [self doReadTimeoutWithExtension:timeoutExtension];
  3890. [callbackPool drain];
  3891. });
  3892. [delegatePool drain];
  3893. });
  3894. }
  3895. else
  3896. {
  3897. [self doReadTimeoutWithExtension:0.0];
  3898. }
  3899. }
  3900. - (void)doReadTimeoutWithExtension:(NSTimeInterval)timeoutExtension
  3901. {
  3902. if (currentRead)
  3903. {
  3904. if (timeoutExtension > 0.0)
  3905. {
  3906. currentRead->timeout += timeoutExtension;
  3907. // Reschedule the timer
  3908. dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (timeoutExtension * NSEC_PER_SEC));
  3909. dispatch_source_set_timer(readTimer, tt, DISPATCH_TIME_FOREVER, 0);
  3910. // Unpause reads, and continue
  3911. flags &= ~kReadsPaused;
  3912. [self doReadData];
  3913. }
  3914. else
  3915. {
  3916. LogVerbose(@"ReadTimeout");
  3917. [self closeWithError:[self readTimeoutError]];
  3918. }
  3919. }
  3920. }
  3921. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3922. #pragma mark Writing
  3923. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3924. - (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag
  3925. {
  3926. if ([data length] == 0) return;
  3927. GCDAsyncWritePacket *packet = [[GCDAsyncWritePacket alloc] initWithData:data timeout:timeout tag:tag];
  3928. dispatch_async(socketQueue, ^{
  3929. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  3930. LogTrace();
  3931. if ((flags & kSocketStarted) && !(flags & kForbidReadsWrites))
  3932. {
  3933. [writeQueue addObject:packet];
  3934. [self maybeDequeueWrite];
  3935. }
  3936. [pool drain];
  3937. });
  3938. // Do not rely on the block being run in order to release the packet,
  3939. // as the queue might get released without the block completing.
  3940. [packet release];
  3941. }
  3942. /**
  3943. * Conditionally starts a new write.
  3944. *
  3945. * It is called when:
  3946. * - a user requests a write
  3947. * - after a write request has finished (to handle the next request)
  3948. * - immediately after the socket opens to handle any pending requests
  3949. *
  3950. * This method also handles auto-disconnect post read/write completion.
  3951. **/
  3952. - (void)maybeDequeueWrite
  3953. {
  3954. LogTrace();
  3955. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  3956. // If we're not currently processing a write AND we have an available write stream
  3957. if ((currentWrite == nil) && (flags & kConnected))
  3958. {
  3959. if ([writeQueue count] > 0)
  3960. {
  3961. // Dequeue the next object in the write queue
  3962. currentWrite = [[writeQueue objectAtIndex:0] retain];
  3963. [writeQueue removeObjectAtIndex:0];
  3964. if ([currentWrite isKindOfClass:[GCDAsyncSpecialPacket class]])
  3965. {
  3966. LogVerbose(@"Dequeued GCDAsyncSpecialPacket");
  3967. // Attempt to start TLS
  3968. flags |= kStartingWriteTLS;
  3969. // This method won't do anything unless both kStartingReadTLS and kStartingWriteTLS are set
  3970. [self maybeStartTLS];
  3971. }
  3972. else
  3973. {
  3974. LogVerbose(@"Dequeued GCDAsyncWritePacket");
  3975. // Setup write timer (if needed)
  3976. [self setupWriteTimerWithTimeout:currentWrite->timeout];
  3977. // Immediately write, if possible
  3978. [self doWriteData];
  3979. }
  3980. }
  3981. else if (flags & kDisconnectAfterWrites)
  3982. {
  3983. if (flags & kDisconnectAfterReads)
  3984. {
  3985. if (([readQueue count] == 0) && (currentRead == nil))
  3986. {
  3987. [self closeWithError:nil];
  3988. }
  3989. }
  3990. else
  3991. {
  3992. [self closeWithError:nil];
  3993. }
  3994. }
  3995. }
  3996. }
  3997. - (void)doWriteData
  3998. {
  3999. LogTrace();
  4000. // This method is called by the writeSource via the socketQueue
  4001. if ((currentWrite == nil) || (flags & kWritesPaused))
  4002. {
  4003. LogVerbose(@"No currentWrite or kWritesPaused");
  4004. // Unable to write at this time
  4005. if ([self usingCFStream])
  4006. {
  4007. // CFWriteStream only fires once when there is available data.
  4008. // It won't fire again until we've invoked CFWriteStreamWrite.
  4009. }
  4010. else
  4011. {
  4012. // If the writeSource is firing, we need to pause it
  4013. // or else it will continue to fire over and over again.
  4014. if (flags & kSocketCanAcceptBytes)
  4015. {
  4016. [self suspendWriteSource];
  4017. }
  4018. }
  4019. return;
  4020. }
  4021. if (!(flags & kSocketCanAcceptBytes))
  4022. {
  4023. LogVerbose(@"No space available to write...");
  4024. // No space available to write.
  4025. if (![self usingCFStream])
  4026. {
  4027. // Need to wait for writeSource to fire and notify us of
  4028. // available space in the socket's internal write buffer.
  4029. [self resumeWriteSource];
  4030. }
  4031. return;
  4032. }
  4033. if (flags & kStartingWriteTLS)
  4034. {
  4035. LogVerbose(@"Waiting for SSL/TLS handshake to complete");
  4036. // The writeQueue is waiting for SSL/TLS handshake to complete.
  4037. if (flags & kStartingReadTLS)
  4038. {
  4039. #if !TARGET_OS_IPHONE
  4040. // We are in the process of a SSL Handshake.
  4041. // We were waiting for available space in the socket's internal OS buffer to continue writing.
  4042. [self continueSSLHandshake];
  4043. #endif
  4044. }
  4045. else
  4046. {
  4047. // We are still waiting for the readQueue to drain and start the SSL/TLS process.
  4048. // We now know we can write to the socket.
  4049. if (![self usingCFStream])
  4050. {
  4051. // Suspend the write source or else it will continue to fire nonstop.
  4052. [self suspendWriteSource];
  4053. }
  4054. }
  4055. return;
  4056. }
  4057. // Note: This method is not called if theCurrentWrite is an GCDAsyncSpecialPacket (startTLS packet)
  4058. BOOL waiting = NO;
  4059. NSError *error = nil;
  4060. size_t bytesWritten = 0;
  4061. if (flags & kSocketSecure)
  4062. {
  4063. #if TARGET_OS_IPHONE
  4064. const uint8_t *buffer = (const uint8_t *)[currentWrite->buffer bytes] + currentWrite->bytesDone;
  4065. NSUInteger bytesToWrite = [currentWrite->buffer length] - currentWrite->bytesDone;
  4066. if (bytesToWrite > SIZE_MAX) // NSUInteger may be bigger than size_t (write param 3)
  4067. {
  4068. bytesToWrite = SIZE_MAX;
  4069. }
  4070. CFIndex result = CFWriteStreamWrite(writeStream, buffer, (CFIndex)bytesToWrite);
  4071. LogVerbose(@"CFWriteStreamWrite(%lu) = %li", bytesToWrite, result);
  4072. if (result < 0)
  4073. {
  4074. error = [NSMakeCollectable(CFWriteStreamCopyError(writeStream)) autorelease];
  4075. }
  4076. else
  4077. {
  4078. bytesWritten = (size_t)result;
  4079. // We always set waiting to true in this scenario.
  4080. // CFStream may have altered our underlying socket to non-blocking.
  4081. // Thus if we attempt to write without a callback, we may end up blocking our queue.
  4082. waiting = YES;
  4083. }
  4084. #else
  4085. // We're going to use the SSLWrite function.
  4086. //
  4087. // OSStatus SSLWrite(SSLContextRef context, const void *data, size_t dataLength, size_t *processed)
  4088. //
  4089. // Parameters:
  4090. // context - An SSL session context reference.
  4091. // data - A pointer to the buffer of data to write.
  4092. // dataLength - The amount, in bytes, of data to write.
  4093. // processed - On return, the length, in bytes, of the data actually written.
  4094. //
  4095. // It sounds pretty straight-forward,
  4096. // but there are a few caveats you should be aware of.
  4097. //
  4098. // The SSLWrite method operates in a non-obvious (and rather annoying) manner.
  4099. // According to the documentation:
  4100. //
  4101. // Because you may configure the underlying connection to operate in a non-blocking manner,
  4102. // a write operation might return errSSLWouldBlock, indicating that less data than requested
  4103. // was actually transferred. In this case, you should repeat the call to SSLWrite until some
  4104. // other result is returned.
  4105. //
  4106. // This sounds perfect, but when our SSLWriteFunction returns errSSLWouldBlock,
  4107. // then the SSLWrite method returns (with the proper errSSLWouldBlock return value),
  4108. // but it sets bytesWritten to bytesToWrite !!
  4109. //
  4110. // In other words, if the SSLWrite function doesn't completely write all the data we tell it to,
  4111. // then it doesn't tell us how many bytes were actually written.
  4112. //
  4113. // You might be wondering:
  4114. // If the SSLWrite function doesn't tell us how many bytes were written,
  4115. // then how in the world are we supposed to update our parameters (buffer & bytesToWrite)
  4116. // for the next time we invoke SSLWrite?
  4117. //
  4118. // The answer is that SSLWrite cached all the data we told it to write,
  4119. // and it will push out that data next time we call SSLWrite.
  4120. // If we call SSLWrite with new data, it will push out the cached data first, and then the new data.
  4121. // If we call SSLWrite with empty data, then it will simply push out the cached data.
  4122. //
  4123. // For this purpose we're going to break large writes into a series of smaller writes.
  4124. // This allows us to report progress back to the delegate.
  4125. OSStatus result;
  4126. BOOL hasCachedDataToWrite = (sslWriteCachedLength > 0);
  4127. BOOL hasNewDataToWrite = YES;
  4128. if (hasCachedDataToWrite)
  4129. {
  4130. size_t processed = 0;
  4131. result = SSLWrite(sslContext, NULL, 0, &processed);
  4132. if (result == noErr)
  4133. {
  4134. bytesWritten = sslWriteCachedLength;
  4135. sslWriteCachedLength = 0;
  4136. if (currentWrite->bytesDone == [currentWrite->buffer length])
  4137. {
  4138. // We've written all data for the current write.
  4139. hasNewDataToWrite = NO;
  4140. }
  4141. }
  4142. else
  4143. {
  4144. if (result == errSSLWouldBlock)
  4145. {
  4146. waiting = YES;
  4147. }
  4148. else
  4149. {
  4150. error = [self sslError:result];
  4151. }
  4152. // Can't write any new data since we were unable to write the cached data.
  4153. hasNewDataToWrite = NO;
  4154. }
  4155. }
  4156. if (hasNewDataToWrite)
  4157. {
  4158. const uint8_t *buffer = (const uint8_t *)[currentWrite->buffer bytes] + currentWrite->bytesDone + bytesWritten;
  4159. NSUInteger bytesToWrite = [currentWrite->buffer length] - currentWrite->bytesDone - bytesWritten;
  4160. if (bytesToWrite > SIZE_MAX) // NSUInteger may be bigger than size_t (write param 3)
  4161. {
  4162. bytesToWrite = SIZE_MAX;
  4163. }
  4164. size_t bytesRemaining = bytesToWrite;
  4165. BOOL keepLooping = YES;
  4166. while (keepLooping)
  4167. {
  4168. size_t sslBytesToWrite = MIN(bytesRemaining, 32768);
  4169. size_t sslBytesWritten = 0;
  4170. result = SSLWrite(sslContext, buffer, sslBytesToWrite, &sslBytesWritten);
  4171. if (result == noErr)
  4172. {
  4173. buffer += sslBytesWritten;
  4174. bytesWritten += sslBytesWritten;
  4175. bytesRemaining -= sslBytesWritten;
  4176. keepLooping = (bytesRemaining > 0);
  4177. }
  4178. else
  4179. {
  4180. if (result == errSSLWouldBlock)
  4181. {
  4182. waiting = YES;
  4183. sslWriteCachedLength = sslBytesToWrite;
  4184. }
  4185. else
  4186. {
  4187. error = [self sslError:result];
  4188. }
  4189. keepLooping = NO;
  4190. }
  4191. } // while (keepLooping)
  4192. } // if (hasNewDataToWrite)
  4193. #endif
  4194. }
  4195. else
  4196. {
  4197. int socketFD = (socket4FD == SOCKET_NULL) ? socket6FD : socket4FD;
  4198. const uint8_t *buffer = (const uint8_t *)[currentWrite->buffer bytes] + currentWrite->bytesDone;
  4199. NSUInteger bytesToWrite = [currentWrite->buffer length] - currentWrite->bytesDone;
  4200. if (bytesToWrite > SIZE_MAX) // NSUInteger may be bigger than size_t (write param 3)
  4201. {
  4202. bytesToWrite = SIZE_MAX;
  4203. }
  4204. ssize_t result = write(socketFD, buffer, (size_t)bytesToWrite);
  4205. LogVerbose(@"wrote to socket = %zd", result);
  4206. // Check results
  4207. if (result < 0)
  4208. {
  4209. if (errno == EWOULDBLOCK)
  4210. {
  4211. waiting = YES;
  4212. }
  4213. else
  4214. {
  4215. error = [self errnoErrorWithReason:@"Error in write() function"];
  4216. }
  4217. }
  4218. else
  4219. {
  4220. bytesWritten = result;
  4221. }
  4222. }
  4223. // We're done with our writing.
  4224. // If we explictly ran into a situation where the socket told us there was no room in the buffer,
  4225. // then we immediately resume listening for notifications.
  4226. //
  4227. // We must do this before we dequeue another write,
  4228. // as that may in turn invoke this method again.
  4229. //
  4230. // Note that if CFStream is involved, it may have maliciously put our socket in blocking mode.
  4231. if (waiting)
  4232. {
  4233. flags &= ~kSocketCanAcceptBytes;
  4234. if (![self usingCFStream])
  4235. {
  4236. [self resumeWriteSource];
  4237. }
  4238. }
  4239. // Check our results
  4240. BOOL done = NO;
  4241. if (bytesWritten > 0)
  4242. {
  4243. // Update total amount read for the current write
  4244. currentWrite->bytesDone += bytesWritten;
  4245. LogVerbose(@"currentWrite->bytesDone = %lu", currentWrite->bytesDone);
  4246. // Is packet done?
  4247. done = (currentWrite->bytesDone == [currentWrite->buffer length]);
  4248. }
  4249. if (done)
  4250. {
  4251. [self completeCurrentWrite];
  4252. if (!error)
  4253. {
  4254. [self maybeDequeueWrite];
  4255. }
  4256. }
  4257. else
  4258. {
  4259. // We were unable to finish writing the data,
  4260. // so we're waiting for another callback to notify us of available space in the lower-level output buffer.
  4261. if (!waiting & !error)
  4262. {
  4263. // This would be the case if our write was able to accept some data, but not all of it.
  4264. flags &= ~kSocketCanAcceptBytes;
  4265. if (![self usingCFStream])
  4266. {
  4267. [self resumeWriteSource];
  4268. }
  4269. }
  4270. if (bytesWritten > 0)
  4271. {
  4272. // We're not done with the entire write, but we have written some bytes
  4273. if (delegateQueue && [delegate respondsToSelector:@selector(socket:didWritePartialDataOfLength:tag:)])
  4274. {
  4275. id theDelegate = delegate;
  4276. GCDAsyncWritePacket *theWrite = currentWrite;
  4277. dispatch_async(delegateQueue, ^{
  4278. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  4279. [theDelegate socket:self didWritePartialDataOfLength:bytesWritten tag:theWrite->tag];
  4280. [pool drain];
  4281. });
  4282. }
  4283. }
  4284. }
  4285. // Check for errors
  4286. if (error)
  4287. {
  4288. [self closeWithError:[self errnoErrorWithReason:@"Error in write() function"]];
  4289. }
  4290. // Do not add any code here without first adding a return statement in the error case above.
  4291. }
  4292. - (void)completeCurrentWrite
  4293. {
  4294. LogTrace();
  4295. NSAssert(currentWrite, @"Trying to complete current write when there is no current write.");
  4296. if (delegateQueue && [delegate respondsToSelector:@selector(socket:didWriteDataWithTag:)])
  4297. {
  4298. id theDelegate = delegate;
  4299. GCDAsyncWritePacket *theWrite = currentWrite;
  4300. dispatch_async(delegateQueue, ^{
  4301. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  4302. [theDelegate socket:self didWriteDataWithTag:theWrite->tag];
  4303. [pool drain];
  4304. });
  4305. }
  4306. [self endCurrentWrite];
  4307. }
  4308. - (void)endCurrentWrite
  4309. {
  4310. if (writeTimer)
  4311. {
  4312. dispatch_source_cancel(writeTimer);
  4313. writeTimer = NULL;
  4314. }
  4315. [currentWrite release];
  4316. currentWrite = nil;
  4317. }
  4318. - (void)setupWriteTimerWithTimeout:(NSTimeInterval)timeout
  4319. {
  4320. if (timeout >= 0.0)
  4321. {
  4322. writeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, socketQueue);
  4323. dispatch_source_set_event_handler(writeTimer, ^{
  4324. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  4325. [self doWriteTimeout];
  4326. [pool drain];
  4327. });
  4328. dispatch_source_t theWriteTimer = writeTimer;
  4329. dispatch_source_set_cancel_handler(writeTimer, ^{
  4330. LogVerbose(@"dispatch_release(writeTimer)");
  4331. dispatch_release(theWriteTimer);
  4332. });
  4333. dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (timeout * NSEC_PER_SEC));
  4334. dispatch_source_set_timer(writeTimer, tt, DISPATCH_TIME_FOREVER, 0);
  4335. dispatch_resume(writeTimer);
  4336. }
  4337. }
  4338. - (void)doWriteTimeout
  4339. {
  4340. // This is a little bit tricky.
  4341. // Ideally we'd like to synchronously query the delegate about a timeout extension.
  4342. // But if we do so synchronously we risk a possible deadlock.
  4343. // So instead we have to do so asynchronously, and callback to ourselves from within the delegate block.
  4344. flags |= kWritesPaused;
  4345. if (delegateQueue && [delegate respondsToSelector:@selector(socket:shouldTimeoutWriteWithTag:elapsed:bytesDone:)])
  4346. {
  4347. id theDelegate = delegate;
  4348. GCDAsyncWritePacket *theWrite = currentWrite;
  4349. dispatch_async(delegateQueue, ^{
  4350. NSAutoreleasePool *delegatePool = [[NSAutoreleasePool alloc] init];
  4351. NSTimeInterval timeoutExtension = 0.0;
  4352. timeoutExtension = [theDelegate socket:self shouldTimeoutWriteWithTag:theWrite->tag
  4353. elapsed:theWrite->timeout
  4354. bytesDone:theWrite->bytesDone];
  4355. dispatch_async(socketQueue, ^{
  4356. NSAutoreleasePool *callbackPool = [[NSAutoreleasePool alloc] init];
  4357. [self doWriteTimeoutWithExtension:timeoutExtension];
  4358. [callbackPool drain];
  4359. });
  4360. [delegatePool drain];
  4361. });
  4362. }
  4363. else
  4364. {
  4365. [self doWriteTimeoutWithExtension:0.0];
  4366. }
  4367. }
  4368. - (void)doWriteTimeoutWithExtension:(NSTimeInterval)timeoutExtension
  4369. {
  4370. if (currentWrite)
  4371. {
  4372. if (timeoutExtension > 0.0)
  4373. {
  4374. currentWrite->timeout += timeoutExtension;
  4375. // Reschedule the timer
  4376. dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (timeoutExtension * NSEC_PER_SEC));
  4377. dispatch_source_set_timer(writeTimer, tt, DISPATCH_TIME_FOREVER, 0);
  4378. // Unpause writes, and continue
  4379. flags &= ~kWritesPaused;
  4380. [self doWriteData];
  4381. }
  4382. else
  4383. {
  4384. LogVerbose(@"WriteTimeout");
  4385. [self closeWithError:[self writeTimeoutError]];
  4386. }
  4387. }
  4388. }
  4389. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4390. #pragma mark Security
  4391. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4392. - (void)startTLS:(NSDictionary *)tlsSettings
  4393. {
  4394. LogTrace();
  4395. if (tlsSettings == nil)
  4396. {
  4397. // Passing nil/NULL to CFReadStreamSetProperty will appear to work the same as passing an empty dictionary,
  4398. // but causes problems if we later try to fetch the remote host's certificate.
  4399. //
  4400. // To be exact, it causes the following to return NULL instead of the normal result:
  4401. // CFReadStreamCopyProperty(readStream, kCFStreamPropertySSLPeerCertificates)
  4402. //
  4403. // So we use an empty dictionary instead, which works perfectly.
  4404. tlsSettings = [NSDictionary dictionary];
  4405. }
  4406. GCDAsyncSpecialPacket *packet = [[GCDAsyncSpecialPacket alloc] initWithTLSSettings:tlsSettings];
  4407. dispatch_async(socketQueue, ^{
  4408. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  4409. if ((flags & kSocketStarted) && !(flags & kQueuedTLS) && !(flags & kForbidReadsWrites))
  4410. {
  4411. [readQueue addObject:packet];
  4412. [writeQueue addObject:packet];
  4413. flags |= kQueuedTLS;
  4414. [self maybeDequeueRead];
  4415. [self maybeDequeueWrite];
  4416. }
  4417. [pool drain];
  4418. });
  4419. [packet release];
  4420. }
  4421. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4422. #pragma mark Security - Mac OS X
  4423. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4424. #if !TARGET_OS_IPHONE
  4425. - (OSStatus)sslReadWithBuffer:(void *)buffer length:(size_t *)bufferLength
  4426. {
  4427. LogVerbose(@"sslReadWithBuffer:%p length:%lu", buffer, (unsigned long)*bufferLength);
  4428. if ((socketFDBytesAvailable == 0) && ([sslReadBuffer length] == 0))
  4429. {
  4430. LogVerbose(@"%@ - No data available to read...", THIS_METHOD);
  4431. // No data available to read.
  4432. //
  4433. // Need to wait for readSource to fire and notify us of
  4434. // available data in the socket's internal read buffer.
  4435. [self resumeReadSource];
  4436. *bufferLength = 0;
  4437. return errSSLWouldBlock;
  4438. }
  4439. size_t totalBytesRead = 0;
  4440. size_t totalBytesLeftToBeRead = *bufferLength;
  4441. BOOL done = NO;
  4442. BOOL socketError = NO;
  4443. //
  4444. // STEP 1 : READ FROM SSL PRE BUFFER
  4445. //
  4446. NSUInteger sslReadBufferLength = [sslReadBuffer length];
  4447. if (sslReadBufferLength > 0)
  4448. {
  4449. LogVerbose(@"%@: Reading from SSL pre buffer...", THIS_METHOD);
  4450. size_t bytesToCopy;
  4451. if (sslReadBufferLength > totalBytesLeftToBeRead)
  4452. bytesToCopy = totalBytesLeftToBeRead;
  4453. else
  4454. bytesToCopy = (size_t)sslReadBufferLength;
  4455. LogVerbose(@"%@: Copying %zu bytes from sslReadBuffer", THIS_METHOD, bytesToCopy);
  4456. memcpy(buffer, [sslReadBuffer mutableBytes], bytesToCopy);
  4457. [sslReadBuffer replaceBytesInRange:NSMakeRange(0, bytesToCopy) withBytes:NULL length:0];
  4458. LogVerbose(@"%@: sslReadBuffer.length = %lu", THIS_METHOD, (unsigned long)[sslReadBuffer length]);
  4459. totalBytesRead += bytesToCopy;
  4460. totalBytesLeftToBeRead -= bytesToCopy;
  4461. done = (totalBytesLeftToBeRead == 0);
  4462. if (done) LogVerbose(@"%@: Complete", THIS_METHOD);
  4463. }
  4464. //
  4465. // STEP 2 : READ FROM SOCKET
  4466. //
  4467. if (!done && (socketFDBytesAvailable > 0))
  4468. {
  4469. LogVerbose(@"%@: Reading from socket...", THIS_METHOD);
  4470. int socketFD = (socket6FD == SOCKET_NULL) ? socket4FD : socket6FD;
  4471. BOOL readIntoPreBuffer;
  4472. size_t bytesToRead;
  4473. uint8_t *buf;
  4474. if (socketFDBytesAvailable > totalBytesLeftToBeRead)
  4475. {
  4476. // Read all available data from socket into sslReadBuffer.
  4477. // Then copy requested amount into dataBuffer.
  4478. LogVerbose(@"%@: Reading into sslReadBuffer...", THIS_METHOD);
  4479. if ([sslReadBuffer length] < socketFDBytesAvailable)
  4480. {
  4481. [sslReadBuffer setLength:socketFDBytesAvailable];
  4482. }
  4483. readIntoPreBuffer = YES;
  4484. bytesToRead = (size_t)socketFDBytesAvailable;
  4485. buf = [sslReadBuffer mutableBytes];
  4486. }
  4487. else
  4488. {
  4489. // Read available data from socket directly into dataBuffer.
  4490. LogVerbose(@"%@: Reading directly into dataBuffer...", THIS_METHOD);
  4491. readIntoPreBuffer = NO;
  4492. bytesToRead = totalBytesLeftToBeRead;
  4493. buf = (uint8_t *)buffer + totalBytesRead;
  4494. }
  4495. ssize_t result = read(socketFD, buf, bytesToRead);
  4496. LogVerbose(@"%@: read from socket = %zd", THIS_METHOD, result);
  4497. if (result < 0)
  4498. {
  4499. LogVerbose(@"%@: read errno = %i", THIS_METHOD, errno);
  4500. if (errno != EWOULDBLOCK)
  4501. {
  4502. socketError = YES;
  4503. }
  4504. socketFDBytesAvailable = 0;
  4505. if (readIntoPreBuffer)
  4506. {
  4507. [sslReadBuffer setLength:0];
  4508. }
  4509. }
  4510. else if (result == 0)
  4511. {
  4512. LogVerbose(@"%@: read EOF", THIS_METHOD);
  4513. socketError = YES;
  4514. socketFDBytesAvailable = 0;
  4515. if (readIntoPreBuffer)
  4516. {
  4517. [sslReadBuffer setLength:0];
  4518. }
  4519. }
  4520. else
  4521. {
  4522. size_t bytesReadFromSocket = result;
  4523. if (socketFDBytesAvailable > bytesReadFromSocket)
  4524. socketFDBytesAvailable -= bytesReadFromSocket;
  4525. else
  4526. socketFDBytesAvailable = 0;
  4527. if (readIntoPreBuffer)
  4528. {
  4529. size_t bytesToCopy = MIN(totalBytesLeftToBeRead, bytesReadFromSocket);
  4530. LogVerbose(@"%@: Copying %zu bytes out of sslReadBuffer", THIS_METHOD, bytesToCopy);
  4531. memcpy((uint8_t *)buffer + totalBytesRead, [sslReadBuffer bytes], bytesToCopy);
  4532. [sslReadBuffer setLength:bytesReadFromSocket];
  4533. [sslReadBuffer replaceBytesInRange:NSMakeRange(0, bytesToCopy) withBytes:NULL length:0];
  4534. totalBytesRead += bytesToCopy;
  4535. totalBytesLeftToBeRead -= bytesToCopy;
  4536. LogVerbose(@"%@: sslReadBuffer.length = %lu", THIS_METHOD, (unsigned long)[sslReadBuffer length]);
  4537. }
  4538. else
  4539. {
  4540. totalBytesRead += bytesReadFromSocket;
  4541. totalBytesLeftToBeRead -= bytesReadFromSocket;
  4542. }
  4543. done = (totalBytesLeftToBeRead == 0);
  4544. if (done) LogVerbose(@"%@: Complete", THIS_METHOD);
  4545. }
  4546. }
  4547. *bufferLength = totalBytesRead;
  4548. if (done)
  4549. return noErr;
  4550. if (socketError)
  4551. return errSSLClosedAbort;
  4552. return errSSLWouldBlock;
  4553. }
  4554. - (OSStatus)sslWriteWithBuffer:(const void *)buffer length:(size_t *)bufferLength
  4555. {
  4556. if (!(flags & kSocketCanAcceptBytes))
  4557. {
  4558. // Unable to write.
  4559. //
  4560. // Need to wait for writeSource to fire and notify us of
  4561. // available space in the socket's internal write buffer.
  4562. [self resumeWriteSource];
  4563. *bufferLength = 0;
  4564. return errSSLWouldBlock;
  4565. }
  4566. size_t bytesToWrite = *bufferLength;
  4567. size_t bytesWritten = 0;
  4568. BOOL done = NO;
  4569. BOOL socketError = NO;
  4570. int socketFD = (socket4FD == SOCKET_NULL) ? socket6FD : socket4FD;
  4571. ssize_t result = write(socketFD, buffer, bytesToWrite);
  4572. if (result < 0)
  4573. {
  4574. if (errno != EWOULDBLOCK)
  4575. {
  4576. socketError = YES;
  4577. }
  4578. flags &= ~kSocketCanAcceptBytes;
  4579. }
  4580. else if (result == 0)
  4581. {
  4582. flags &= ~kSocketCanAcceptBytes;
  4583. }
  4584. else
  4585. {
  4586. bytesWritten = result;
  4587. done = (bytesWritten == bytesToWrite);
  4588. }
  4589. *bufferLength = bytesWritten;
  4590. if (done)
  4591. return noErr;
  4592. if (socketError)
  4593. return errSSLClosedAbort;
  4594. return errSSLWouldBlock;
  4595. }
  4596. static OSStatus SSLReadFunction(SSLConnectionRef connection, void *data, size_t *dataLength)
  4597. {
  4598. GCDAsyncSocket *asyncSocket = (GCDAsyncSocket *)connection;
  4599. NSCAssert(dispatch_get_current_queue() == asyncSocket->socketQueue, @"What the deuce?");
  4600. return [asyncSocket sslReadWithBuffer:data length:dataLength];
  4601. }
  4602. static OSStatus SSLWriteFunction(SSLConnectionRef connection, const void *data, size_t *dataLength)
  4603. {
  4604. GCDAsyncSocket *asyncSocket = (GCDAsyncSocket *)connection;
  4605. NSCAssert(dispatch_get_current_queue() == asyncSocket->socketQueue, @"What the deuce?");
  4606. return [asyncSocket sslWriteWithBuffer:data length:dataLength];
  4607. }
  4608. - (void)maybeStartTLS
  4609. {
  4610. LogTrace();
  4611. // We can't start TLS until:
  4612. // - All queued reads prior to the user calling startTLS are complete
  4613. // - All queued writes prior to the user calling startTLS are complete
  4614. //
  4615. // We'll know these conditions are met when both kStartingReadTLS and kStartingWriteTLS are set
  4616. if ((flags & kStartingReadTLS) && (flags & kStartingWriteTLS))
  4617. {
  4618. LogVerbose(@"Starting TLS...");
  4619. OSStatus status;
  4620. GCDAsyncSpecialPacket *tlsPacket = (GCDAsyncSpecialPacket *)currentRead;
  4621. NSDictionary *tlsSettings = tlsPacket->tlsSettings;
  4622. // Create SSLContext, and setup IO callbacks and connection ref
  4623. BOOL isServer = [[tlsSettings objectForKey:(NSString *)kCFStreamSSLIsServer] boolValue];
  4624. status = SSLNewContext(isServer, &sslContext);
  4625. if (status != noErr)
  4626. {
  4627. [self closeWithError:[self otherError:@"Error in SSLNewContext"]];
  4628. return;
  4629. }
  4630. status = SSLSetIOFuncs(sslContext, &SSLReadFunction, &SSLWriteFunction);
  4631. if (status != noErr)
  4632. {
  4633. [self closeWithError:[self otherError:@"Error in SSLSetIOFuncs"]];
  4634. return;
  4635. }
  4636. status = SSLSetConnection(sslContext, (SSLConnectionRef)self);
  4637. if (status != noErr)
  4638. {
  4639. [self closeWithError:[self otherError:@"Error in SSLSetConnection"]];
  4640. return;
  4641. }
  4642. // Configure SSLContext from given settings
  4643. //
  4644. // Checklist:
  4645. // 1. kCFStreamSSLPeerName
  4646. // 2. kCFStreamSSLAllowsAnyRoot
  4647. // 3. kCFStreamSSLAllowsExpiredRoots
  4648. // 4. kCFStreamSSLValidatesCertificateChain
  4649. // 5. kCFStreamSSLAllowsExpiredCertificates
  4650. // 6. kCFStreamSSLCertificates
  4651. // 7. kCFStreamSSLLevel
  4652. // 8. GCDAsyncSocketSSLCipherSuites
  4653. // 9. GCDAsyncSocketSSLDiffieHellmanParameters
  4654. id value;
  4655. // 1. kCFStreamSSLPeerName
  4656. value = [tlsSettings objectForKey:(NSString *)kCFStreamSSLPeerName];
  4657. if ([value isKindOfClass:[NSString class]])
  4658. {
  4659. NSString *peerName = (NSString *)value;
  4660. const char *peer = [peerName UTF8String];
  4661. size_t peerLen = strlen(peer);
  4662. status = SSLSetPeerDomainName(sslContext, peer, peerLen);
  4663. if (status != noErr)
  4664. {
  4665. [self closeWithError:[self otherError:@"Error in SSLSetPeerDomainName"]];
  4666. return;
  4667. }
  4668. }
  4669. // 2. kCFStreamSSLAllowsAnyRoot
  4670. value = [tlsSettings objectForKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
  4671. if (value)
  4672. {
  4673. BOOL allowsAnyRoot = [value boolValue];
  4674. status = SSLSetAllowsAnyRoot(sslContext, allowsAnyRoot);
  4675. if (status != noErr)
  4676. {
  4677. [self closeWithError:[self otherError:@"Error in SSLSetAllowsAnyRoot"]];
  4678. return;
  4679. }
  4680. }
  4681. // 3. kCFStreamSSLAllowsExpiredRoots
  4682. value = [tlsSettings objectForKey:(NSString *)kCFStreamSSLAllowsExpiredRoots];
  4683. if (value)
  4684. {
  4685. BOOL allowsExpiredRoots = [value boolValue];
  4686. status = SSLSetAllowsExpiredRoots(sslContext, allowsExpiredRoots);
  4687. if (status != noErr)
  4688. {
  4689. [self closeWithError:[self otherError:@"Error in SSLSetAllowsExpiredRoots"]];
  4690. return;
  4691. }
  4692. }
  4693. // 4. kCFStreamSSLValidatesCertificateChain
  4694. value = [tlsSettings objectForKey:(NSString *)kCFStreamSSLValidatesCertificateChain];
  4695. if (value)
  4696. {
  4697. BOOL validatesCertChain = [value boolValue];
  4698. status = SSLSetEnableCertVerify(sslContext, validatesCertChain);
  4699. if (status != noErr)
  4700. {
  4701. [self closeWithError:[self otherError:@"Error in SSLSetEnableCertVerify"]];
  4702. return;
  4703. }
  4704. }
  4705. // 5. kCFStreamSSLAllowsExpiredCertificates
  4706. value = [tlsSettings objectForKey:(NSString *)kCFStreamSSLAllowsExpiredCertificates];
  4707. if (value)
  4708. {
  4709. BOOL allowsExpiredCerts = [value boolValue];
  4710. status = SSLSetAllowsExpiredCerts(sslContext, allowsExpiredCerts);
  4711. if (status != noErr)
  4712. {
  4713. [self closeWithError:[self otherError:@"Error in SSLSetAllowsExpiredCerts"]];
  4714. return;
  4715. }
  4716. }
  4717. // 6. kCFStreamSSLCertificates
  4718. value = [tlsSettings objectForKey:(NSString *)kCFStreamSSLCertificates];
  4719. if (value)
  4720. {
  4721. CFArrayRef certs = (CFArrayRef)value;
  4722. status = SSLSetCertificate(sslContext, certs);
  4723. if (status != noErr)
  4724. {
  4725. [self closeWithError:[self otherError:@"Error in SSLSetCertificate"]];
  4726. return;
  4727. }
  4728. }
  4729. // 7. kCFStreamSSLLevel
  4730. value = [tlsSettings objectForKey:(NSString *)kCFStreamSSLLevel];
  4731. if (value)
  4732. {
  4733. NSString *sslLevel = (NSString *)value;
  4734. if ([sslLevel isEqualToString:(NSString *)kCFStreamSocketSecurityLevelSSLv2])
  4735. {
  4736. // kCFStreamSocketSecurityLevelSSLv2:
  4737. //
  4738. // Specifies that SSL version 2 be set as the security protocol.
  4739. SSLSetProtocolVersionEnabled(sslContext, kSSLProtocolAll, NO);
  4740. SSLSetProtocolVersionEnabled(sslContext, kSSLProtocol2, YES);
  4741. }
  4742. else if ([sslLevel isEqualToString:(NSString *)kCFStreamSocketSecurityLevelSSLv3])
  4743. {
  4744. // kCFStreamSocketSecurityLevelSSLv3:
  4745. //
  4746. // Specifies that SSL version 3 be set as the security protocol.
  4747. // If SSL version 3 is not available, specifies that SSL version 2 be set as the security protocol.
  4748. SSLSetProtocolVersionEnabled(sslContext, kSSLProtocolAll, NO);
  4749. SSLSetProtocolVersionEnabled(sslContext, kSSLProtocol2, YES);
  4750. SSLSetProtocolVersionEnabled(sslContext, kSSLProtocol3, YES);
  4751. }
  4752. else if ([sslLevel isEqualToString:(NSString *)kCFStreamSocketSecurityLevelTLSv1])
  4753. {
  4754. // kCFStreamSocketSecurityLevelTLSv1:
  4755. //
  4756. // Specifies that TLS version 1 be set as the security protocol.
  4757. SSLSetProtocolVersionEnabled(sslContext, kSSLProtocolAll, NO);
  4758. SSLSetProtocolVersionEnabled(sslContext, kTLSProtocol1, YES);
  4759. }
  4760. else if ([sslLevel isEqualToString:(NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL])
  4761. {
  4762. // kCFStreamSocketSecurityLevelNegotiatedSSL:
  4763. //
  4764. // Specifies that the highest level security protocol that can be negotiated be used.
  4765. SSLSetProtocolVersionEnabled(sslContext, kSSLProtocolAll, YES);
  4766. }
  4767. }
  4768. // 8. GCDAsyncSocketSSLCipherSuites
  4769. value = [tlsSettings objectForKey:GCDAsyncSocketSSLCipherSuites];
  4770. if (value)
  4771. {
  4772. NSArray *cipherSuites = (NSArray *)value;
  4773. NSUInteger numberCiphers = [cipherSuites count];
  4774. SSLCipherSuite ciphers[numberCiphers];
  4775. NSUInteger cipherIndex;
  4776. for (cipherIndex = 0; cipherIndex < numberCiphers; cipherIndex++)
  4777. {
  4778. NSNumber *cipherObject = [cipherSuites objectAtIndex:cipherIndex];
  4779. ciphers[cipherIndex] = [cipherObject shortValue];
  4780. }
  4781. status = SSLSetEnabledCiphers(sslContext, ciphers, numberCiphers);
  4782. if (status != noErr)
  4783. {
  4784. [self closeWithError:[self otherError:@"Error in SSLSetEnabledCiphers"]];
  4785. return;
  4786. }
  4787. }
  4788. // 9. GCDAsyncSocketSSLDiffieHellmanParameters
  4789. value = [tlsSettings objectForKey:GCDAsyncSocketSSLDiffieHellmanParameters];
  4790. if (value)
  4791. {
  4792. NSData *diffieHellmanData = (NSData *)value;
  4793. status = SSLSetDiffieHellmanParams(sslContext, [diffieHellmanData bytes], [diffieHellmanData length]);
  4794. if (status != noErr)
  4795. {
  4796. [self closeWithError:[self otherError:@"Error in SSLSetDiffieHellmanParams"]];
  4797. return;
  4798. }
  4799. }
  4800. // Setup the sslReadBuffer
  4801. //
  4802. // If there is any data in the partialReadBuffer,
  4803. // this needs to be moved into the sslReadBuffer,
  4804. // as this data is now part of the secure read stream.
  4805. sslReadBuffer = [[NSMutableData alloc] init];
  4806. if ([partialReadBuffer length] > 0)
  4807. {
  4808. [sslReadBuffer appendData:partialReadBuffer];
  4809. [partialReadBuffer setLength:0];
  4810. }
  4811. // Start the SSL Handshake process
  4812. [self continueSSLHandshake];
  4813. }
  4814. }
  4815. - (void)continueSSLHandshake
  4816. {
  4817. LogTrace();
  4818. // If the return value is noErr, the session is ready for normal secure communication.
  4819. // If the return value is errSSLWouldBlock, the SSLHandshake function must be called again.
  4820. // Otherwise, the return value indicates an error code.
  4821. OSStatus status = SSLHandshake(sslContext);
  4822. if (status == noErr)
  4823. {
  4824. LogVerbose(@"SSLHandshake complete");
  4825. flags &= ~kStartingReadTLS;
  4826. flags &= ~kStartingWriteTLS;
  4827. flags |= kSocketSecure;
  4828. if (delegateQueue && [delegate respondsToSelector:@selector(socketDidSecure:)])
  4829. {
  4830. id theDelegate = delegate;
  4831. dispatch_async(delegateQueue, ^{
  4832. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  4833. [theDelegate socketDidSecure:self];
  4834. [pool drain];
  4835. });
  4836. }
  4837. [self endCurrentRead];
  4838. [self endCurrentWrite];
  4839. [self maybeDequeueRead];
  4840. [self maybeDequeueWrite];
  4841. }
  4842. else if (status == errSSLWouldBlock)
  4843. {
  4844. LogVerbose(@"SSLHandshake continues...");
  4845. // Handshake continues...
  4846. //
  4847. // This method will be called again from doReadData or doWriteData.
  4848. }
  4849. else
  4850. {
  4851. [self closeWithError:[self sslError:status]];
  4852. }
  4853. }
  4854. #endif
  4855. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4856. #pragma mark Security - iOS
  4857. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4858. #if TARGET_OS_IPHONE
  4859. - (void)finishSSLHandshake
  4860. {
  4861. LogTrace();
  4862. if ((flags & kStartingReadTLS) && (flags & kStartingWriteTLS))
  4863. {
  4864. flags &= ~kStartingReadTLS;
  4865. flags &= ~kStartingWriteTLS;
  4866. flags |= kSocketSecure;
  4867. if (delegateQueue && [delegate respondsToSelector:@selector(socketDidSecure:)])
  4868. {
  4869. id theDelegate = delegate;
  4870. dispatch_async(delegateQueue, ^{
  4871. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  4872. [theDelegate socketDidSecure:self];
  4873. [pool drain];
  4874. });
  4875. }
  4876. [self endCurrentRead];
  4877. [self endCurrentWrite];
  4878. [self maybeDequeueRead];
  4879. [self maybeDequeueWrite];
  4880. }
  4881. }
  4882. - (void)abortSSLHandshake:(NSError *)error
  4883. {
  4884. LogTrace();
  4885. if ((flags & kStartingReadTLS) && (flags & kStartingWriteTLS))
  4886. {
  4887. flags &= ~kStartingReadTLS;
  4888. flags &= ~kStartingWriteTLS;
  4889. [self closeWithError:error];
  4890. }
  4891. }
  4892. - (void)maybeStartTLS
  4893. {
  4894. LogTrace();
  4895. // We can't start TLS until:
  4896. // - All queued reads prior to the user calling startTLS are complete
  4897. // - All queued writes prior to the user calling startTLS are complete
  4898. //
  4899. // We'll know these conditions are met when both kStartingReadTLS and kStartingWriteTLS are set
  4900. if ((flags & kStartingReadTLS) && (flags & kStartingWriteTLS))
  4901. {
  4902. LogVerbose(@"Starting TLS...");
  4903. if ([partialReadBuffer length] > 0)
  4904. {
  4905. NSString *msg = @"Invalid TLS transition. Handshake has already been read from socket.";
  4906. [self closeWithError:[self otherError:msg]];
  4907. return;
  4908. }
  4909. [self suspendReadSource];
  4910. [self suspendWriteSource];
  4911. socketFDBytesAvailable = 0;
  4912. flags &= ~kSocketCanAcceptBytes;
  4913. flags &= ~kSecureSocketHasBytesAvailable;
  4914. if (![self createReadAndWriteStream])
  4915. {
  4916. [self closeWithError:[self otherError:@"Error in CFStreamCreatePairWithSocket"]];
  4917. return;
  4918. }
  4919. if (![self registerForStreamCallbacksIncludingReadWrite:YES])
  4920. {
  4921. [self closeWithError:[self otherError:@"Error in CFStreamSetClient"]];
  4922. return;
  4923. }
  4924. if (![self addStreamsToRunLoop])
  4925. {
  4926. [self closeWithError:[self otherError:@"Error in CFStreamScheduleWithRunLoop"]];
  4927. return;
  4928. }
  4929. NSAssert([currentRead isKindOfClass:[GCDAsyncSpecialPacket class]], @"Invalid read packet for startTLS");
  4930. NSAssert([currentWrite isKindOfClass:[GCDAsyncSpecialPacket class]], @"Invalid write packet for startTLS");
  4931. GCDAsyncSpecialPacket *tlsPacket = (GCDAsyncSpecialPacket *)currentRead;
  4932. NSDictionary *tlsSettings = tlsPacket->tlsSettings;
  4933. // Getting an error concerning kCFStreamPropertySSLSettings ?
  4934. // You need to add the CFNetwork framework to your iOS application.
  4935. BOOL r1 = CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (CFDictionaryRef)tlsSettings);
  4936. BOOL r2 = CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (CFDictionaryRef)tlsSettings);
  4937. // For some reason, starting around the time of iOS 4.3,
  4938. // the first call to set the kCFStreamPropertySSLSettings will return true,
  4939. // but the second will return false.
  4940. //
  4941. // Order doesn't seem to matter.
  4942. // So you could call CFReadStreamSetProperty and then CFWriteStreamSetProperty, or you could reverse the order.
  4943. // Either way, the first call will return true, and the second returns false.
  4944. //
  4945. // Interestingly, this doesn't seem to affect anything.
  4946. // Which is not altogether unusual, as the documentation seems to suggest that (for many settings)
  4947. // setting it on one side of the stream automatically sets it for the other side of the stream.
  4948. //
  4949. // Although there isn't anything in the documentation to suggest that the second attempt would fail.
  4950. //
  4951. // Furthermore, this only seems to affect streams that are negotiating a security upgrade.
  4952. // In other words, the socket gets connected, there is some back-and-forth communication over the unsecure
  4953. // connection, and then a startTLS is issued.
  4954. // So this mostly affects newer protocols (XMPP, IMAP) as opposed to older protocols (HTTPS).
  4955. if (!r1 && !r2) // Yes, the && is correct - workaround for apple bug.
  4956. {
  4957. [self closeWithError:[self otherError:@"Error in CFStreamSetProperty"]];
  4958. return;
  4959. }
  4960. if (![self openStreams])
  4961. {
  4962. [self closeWithError:[self otherError:@"Error in CFStreamOpen"]];
  4963. return;
  4964. }
  4965. LogVerbose(@"Waiting for SSL Handshake to complete...");
  4966. }
  4967. }
  4968. #endif
  4969. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4970. #pragma mark CFStream
  4971. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4972. #if TARGET_OS_IPHONE
  4973. + (void)startListenerThreadIfNeeded
  4974. {
  4975. static dispatch_once_t predicate;
  4976. dispatch_once(&predicate, ^{
  4977. listenerThread = [[NSThread alloc] initWithTarget:self
  4978. selector:@selector(listenerThread)
  4979. object:nil];
  4980. [listenerThread start];
  4981. });
  4982. }
  4983. + (void)listenerThread
  4984. {
  4985. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  4986. LogInfo(@"ListenerThread: Started");
  4987. // We can't run the run loop unless it has an associated input source or a timer.
  4988. // So we'll just create a timer that will never fire - unless the server runs for a decades.
  4989. [NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow]
  4990. target:self
  4991. selector:@selector(ignore:)
  4992. userInfo:nil
  4993. repeats:YES];
  4994. [[NSRunLoop currentRunLoop] run];
  4995. LogInfo(@"ListenerThread: Stopped");
  4996. [pool drain];
  4997. }
  4998. + (void)addStreamListener:(GCDAsyncSocket *)asyncSocket
  4999. {
  5000. LogTrace();
  5001. NSAssert([NSThread currentThread] == listenerThread, @"Invoked on wrong thread");
  5002. CFRunLoopRef runLoop = CFRunLoopGetCurrent();
  5003. if (asyncSocket->readStream)
  5004. CFReadStreamScheduleWithRunLoop(asyncSocket->readStream, runLoop, kCFRunLoopDefaultMode);
  5005. if (asyncSocket->writeStream)
  5006. CFWriteStreamScheduleWithRunLoop(asyncSocket->writeStream, runLoop, kCFRunLoopDefaultMode);
  5007. }
  5008. + (void)removeStreamListener:(GCDAsyncSocket *)asyncSocket
  5009. {
  5010. LogTrace();
  5011. NSAssert([NSThread currentThread] == listenerThread, @"Invoked on wrong thread");
  5012. CFRunLoopRef runLoop = CFRunLoopGetCurrent();
  5013. if (asyncSocket->readStream)
  5014. CFReadStreamUnscheduleFromRunLoop(asyncSocket->readStream, runLoop, kCFRunLoopDefaultMode);
  5015. if (asyncSocket->writeStream)
  5016. CFWriteStreamUnscheduleFromRunLoop(asyncSocket->writeStream, runLoop, kCFRunLoopDefaultMode);
  5017. }
  5018. static void CFReadStreamCallback (CFReadStreamRef stream, CFStreamEventType type, void *pInfo)
  5019. {
  5020. GCDAsyncSocket *asyncSocket = [(GCDAsyncSocket *)pInfo retain];
  5021. switch(type)
  5022. {
  5023. case kCFStreamEventHasBytesAvailable:
  5024. {
  5025. dispatch_async(asyncSocket->socketQueue, ^{
  5026. LogCVerbose(@"CFReadStreamCallback - HasBytesAvailable");
  5027. if (asyncSocket->readStream != stream)
  5028. return_from_block;
  5029. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  5030. if ((asyncSocket->flags & kStartingReadTLS) && (asyncSocket->flags & kStartingWriteTLS))
  5031. {
  5032. // If we set kCFStreamPropertySSLSettings before we opened the streams, this might be a lie.
  5033. // (A callback related to the tcp stream, but not to the SSL layer).
  5034. if (CFReadStreamHasBytesAvailable(asyncSocket->readStream))
  5035. {
  5036. asyncSocket->flags |= kSecureSocketHasBytesAvailable;
  5037. [asyncSocket finishSSLHandshake];
  5038. }
  5039. }
  5040. else
  5041. {
  5042. asyncSocket->flags |= kSecureSocketHasBytesAvailable;
  5043. [asyncSocket doReadData];
  5044. }
  5045. [pool drain];
  5046. });
  5047. break;
  5048. }
  5049. default:
  5050. {
  5051. NSError *error = NSMakeCollectable(CFReadStreamCopyError(stream));
  5052. if (error == nil && type == kCFStreamEventEndEncountered)
  5053. {
  5054. error = [[asyncSocket connectionClosedError] retain];
  5055. }
  5056. dispatch_async(asyncSocket->socketQueue, ^{
  5057. LogCVerbose(@"CFReadStreamCallback - Other");
  5058. if (asyncSocket->readStream != stream)
  5059. return_from_block;
  5060. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  5061. if ((asyncSocket->flags & kStartingReadTLS) && (asyncSocket->flags & kStartingWriteTLS))
  5062. {
  5063. [asyncSocket abortSSLHandshake:error];
  5064. }
  5065. else
  5066. {
  5067. [asyncSocket closeWithError:error];
  5068. }
  5069. [pool drain];
  5070. });
  5071. [error release];
  5072. break;
  5073. }
  5074. }
  5075. [asyncSocket release];
  5076. }
  5077. static void CFWriteStreamCallback (CFWriteStreamRef stream, CFStreamEventType type, void *pInfo)
  5078. {
  5079. GCDAsyncSocket *asyncSocket = [(GCDAsyncSocket *)pInfo retain];
  5080. switch(type)
  5081. {
  5082. case kCFStreamEventCanAcceptBytes:
  5083. {
  5084. dispatch_async(asyncSocket->socketQueue, ^{
  5085. LogCVerbose(@"CFWriteStreamCallback - CanAcceptBytes");
  5086. if (asyncSocket->writeStream != stream)
  5087. return_from_block;
  5088. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  5089. if ((asyncSocket->flags & kStartingReadTLS) && (asyncSocket->flags & kStartingWriteTLS))
  5090. {
  5091. // If we set kCFStreamPropertySSLSettings before we opened the streams, this might be a lie.
  5092. // (A callback related to the tcp stream, but not to the SSL layer).
  5093. if (CFWriteStreamCanAcceptBytes(asyncSocket->writeStream))
  5094. {
  5095. asyncSocket->flags |= kSocketCanAcceptBytes;
  5096. [asyncSocket finishSSLHandshake];
  5097. }
  5098. }
  5099. else
  5100. {
  5101. asyncSocket->flags |= kSocketCanAcceptBytes;
  5102. [asyncSocket doWriteData];
  5103. }
  5104. [pool drain];
  5105. });
  5106. break;
  5107. }
  5108. default:
  5109. {
  5110. NSError *error = NSMakeCollectable(CFWriteStreamCopyError(stream));
  5111. if (error == nil && type == kCFStreamEventEndEncountered)
  5112. {
  5113. error = [[asyncSocket connectionClosedError] retain];
  5114. }
  5115. dispatch_async(asyncSocket->socketQueue, ^{
  5116. LogCVerbose(@"CFWriteStreamCallback - Other");
  5117. if (asyncSocket->writeStream != stream)
  5118. return_from_block;
  5119. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  5120. if ((asyncSocket->flags & kStartingReadTLS) && (asyncSocket->flags & kStartingWriteTLS))
  5121. {
  5122. [asyncSocket abortSSLHandshake:error];
  5123. }
  5124. else
  5125. {
  5126. [asyncSocket closeWithError:error];
  5127. }
  5128. [pool drain];
  5129. });
  5130. [error release];
  5131. break;
  5132. }
  5133. }
  5134. [asyncSocket release];
  5135. }
  5136. - (BOOL)createReadAndWriteStream
  5137. {
  5138. LogTrace();
  5139. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  5140. if (readStream || writeStream)
  5141. {
  5142. // Streams already created
  5143. return YES;
  5144. }
  5145. int socketFD = (socket6FD == SOCKET_NULL) ? socket4FD : socket6FD;
  5146. if (socketFD == SOCKET_NULL)
  5147. {
  5148. // Cannot create streams without a file descriptor
  5149. return NO;
  5150. }
  5151. if (![self isConnected])
  5152. {
  5153. // Cannot create streams until file descriptor is connected
  5154. return NO;
  5155. }
  5156. LogVerbose(@"Creating read and write stream...");
  5157. CFStreamCreatePairWithSocket(NULL, (CFSocketNativeHandle)socketFD, &readStream, &writeStream);
  5158. // The kCFStreamPropertyShouldCloseNativeSocket property should be false by default (for our case).
  5159. // But let's not take any chances.
  5160. if (readStream)
  5161. CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse);
  5162. if (writeStream)
  5163. CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse);
  5164. if ((readStream == NULL) || (writeStream == NULL))
  5165. {
  5166. LogWarn(@"Unable to create read and write stream...");
  5167. if (readStream)
  5168. {
  5169. CFReadStreamClose(readStream);
  5170. CFRelease(readStream);
  5171. readStream = NULL;
  5172. }
  5173. if (writeStream)
  5174. {
  5175. CFWriteStreamClose(writeStream);
  5176. CFRelease(writeStream);
  5177. writeStream = NULL;
  5178. }
  5179. return NO;
  5180. }
  5181. return YES;
  5182. }
  5183. - (BOOL)registerForStreamCallbacksIncludingReadWrite:(BOOL)includeReadWrite
  5184. {
  5185. LogVerbose(@"%@ %@", THIS_METHOD, (includeReadWrite ? @"YES" : @"NO"));
  5186. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  5187. NSAssert((readStream != NULL && writeStream != NULL), @"Read/Write stream is null");
  5188. streamContext.version = 0;
  5189. streamContext.info = self;
  5190. streamContext.retain = nil;
  5191. streamContext.release = nil;
  5192. streamContext.copyDescription = nil;
  5193. CFOptionFlags readStreamEvents = kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered;
  5194. if (includeReadWrite)
  5195. readStreamEvents |= kCFStreamEventHasBytesAvailable;
  5196. if (!CFReadStreamSetClient(readStream, readStreamEvents, &CFReadStreamCallback, &streamContext))
  5197. {
  5198. return NO;
  5199. }
  5200. CFOptionFlags writeStreamEvents = kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered;
  5201. if (includeReadWrite)
  5202. writeStreamEvents |= kCFStreamEventCanAcceptBytes;
  5203. if (!CFWriteStreamSetClient(writeStream, writeStreamEvents, &CFWriteStreamCallback, &streamContext))
  5204. {
  5205. return NO;
  5206. }
  5207. return YES;
  5208. }
  5209. - (BOOL)addStreamsToRunLoop
  5210. {
  5211. LogTrace();
  5212. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  5213. NSAssert((readStream != NULL && writeStream != NULL), @"Read/Write stream is null");
  5214. if (!(flags & kAddedStreamListener))
  5215. {
  5216. LogVerbose(@"Adding streams to runloop...");
  5217. [[self class] startListenerThreadIfNeeded];
  5218. [[self class] performSelector:@selector(addStreamListener:)
  5219. onThread:listenerThread
  5220. withObject:self
  5221. waitUntilDone:YES];
  5222. flags |= kAddedStreamListener;
  5223. }
  5224. return YES;
  5225. }
  5226. - (void)removeStreamsFromRunLoop
  5227. {
  5228. LogTrace();
  5229. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  5230. NSAssert((readStream != NULL && writeStream != NULL), @"Read/Write stream is null");
  5231. if (flags & kAddedStreamListener)
  5232. {
  5233. LogVerbose(@"Removing streams from runloop...");
  5234. [[self class] performSelector:@selector(removeStreamListener:)
  5235. onThread:listenerThread
  5236. withObject:self
  5237. waitUntilDone:YES];
  5238. flags &= ~kAddedStreamListener;
  5239. }
  5240. }
  5241. - (BOOL)openStreams
  5242. {
  5243. LogTrace();
  5244. NSAssert(dispatch_get_current_queue() == socketQueue, @"Must be dispatched on socketQueue");
  5245. NSAssert((readStream != NULL && writeStream != NULL), @"Read/Write stream is null");
  5246. CFStreamStatus readStatus = CFReadStreamGetStatus(readStream);
  5247. CFStreamStatus writeStatus = CFWriteStreamGetStatus(writeStream);
  5248. if ((readStatus == kCFStreamStatusNotOpen) || (writeStatus == kCFStreamStatusNotOpen))
  5249. {
  5250. LogVerbose(@"Opening read and write stream...");
  5251. BOOL r1 = CFReadStreamOpen(readStream);
  5252. BOOL r2 = CFWriteStreamOpen(writeStream);
  5253. if (!r1 || !r2)
  5254. {
  5255. LogError(@"Error in CFStreamOpen");
  5256. return NO;
  5257. }
  5258. }
  5259. return YES;
  5260. }
  5261. #endif
  5262. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5263. #pragma mark Advanced
  5264. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5265. - (void)performBlock:(dispatch_block_t)block
  5266. {
  5267. dispatch_sync(socketQueue, block);
  5268. }
  5269. - (int)socketFD
  5270. {
  5271. if (dispatch_get_current_queue() != socketQueue)
  5272. {
  5273. LogWarn(@"%@ - Method only available from within the context of a performBlock: invocation", THIS_METHOD);
  5274. return SOCKET_NULL;
  5275. }
  5276. if (socket4FD != SOCKET_NULL)
  5277. return socket4FD;
  5278. else
  5279. return socket6FD;
  5280. }
  5281. - (int)socket4FD
  5282. {
  5283. if (dispatch_get_current_queue() != socketQueue)
  5284. {
  5285. LogWarn(@"%@ - Method only available from within the context of a performBlock: invocation", THIS_METHOD);
  5286. return SOCKET_NULL;
  5287. }
  5288. return socket4FD;
  5289. }
  5290. - (int)socket6FD
  5291. {
  5292. if (dispatch_get_current_queue() != socketQueue)
  5293. {
  5294. LogWarn(@"%@ - Method only available from within the context of a performBlock: invocation", THIS_METHOD);
  5295. return SOCKET_NULL;
  5296. }
  5297. return socket6FD;
  5298. }
  5299. #if TARGET_OS_IPHONE
  5300. - (CFReadStreamRef)readStream
  5301. {
  5302. if (dispatch_get_current_queue() != socketQueue)
  5303. {
  5304. LogWarn(@"%@ - Method only available from within the context of a performBlock: invocation", THIS_METHOD);
  5305. return NULL;
  5306. }
  5307. if (readStream == NULL)
  5308. [self createReadAndWriteStream];
  5309. return readStream;
  5310. }
  5311. - (CFWriteStreamRef)writeStream
  5312. {
  5313. if (dispatch_get_current_queue() != socketQueue)
  5314. {
  5315. LogWarn(@"%@ - Method only available from within the context of a performBlock: invocation", THIS_METHOD);
  5316. return NULL;
  5317. }
  5318. if (writeStream == NULL)
  5319. [self createReadAndWriteStream];
  5320. return writeStream;
  5321. }
  5322. - (BOOL)enableBackgroundingOnSocketWithCaveat:(BOOL)caveat
  5323. {
  5324. if (![self createReadAndWriteStream])
  5325. {
  5326. // Error occured creating streams (perhaps socket isn't open)
  5327. return NO;
  5328. }
  5329. BOOL r1, r2;
  5330. LogVerbose(@"Enabling backgrouding on socket");
  5331. r1 = CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
  5332. r2 = CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
  5333. if (!r1 || !r2)
  5334. {
  5335. return NO;
  5336. }
  5337. if (!caveat)
  5338. {
  5339. if (![self openStreams])
  5340. {
  5341. return NO;
  5342. }
  5343. }
  5344. return YES;
  5345. }
  5346. - (BOOL)enableBackgroundingOnSocket
  5347. {
  5348. LogTrace();
  5349. if (dispatch_get_current_queue() != socketQueue)
  5350. {
  5351. LogWarn(@"%@ - Method only available from within the context of a performBlock: invocation", THIS_METHOD);
  5352. return NO;
  5353. }
  5354. return [self enableBackgroundingOnSocketWithCaveat:NO];
  5355. }
  5356. - (BOOL)enableBackgroundingOnSocketWithCaveat // Deprecated in iOS 4.???
  5357. {
  5358. // This method was created as a workaround for a bug in iOS.
  5359. // Apple has since fixed this bug.
  5360. // I'm not entirely sure which version of iOS they fixed it in...
  5361. LogTrace();
  5362. if (dispatch_get_current_queue() != socketQueue)
  5363. {
  5364. LogWarn(@"%@ - Method only available from within the context of a performBlock: invocation", THIS_METHOD);
  5365. return NO;
  5366. }
  5367. return [self enableBackgroundingOnSocketWithCaveat:YES];
  5368. }
  5369. #else
  5370. - (SSLContextRef)sslContext
  5371. {
  5372. if (dispatch_get_current_queue() != socketQueue)
  5373. {
  5374. LogWarn(@"%@ - Method only available from within the context of a performBlock: invocation", THIS_METHOD);
  5375. return NULL;
  5376. }
  5377. return sslContext;
  5378. }
  5379. #endif
  5380. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5381. #pragma mark Class Methods
  5382. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5383. + (NSString *)hostFromSockaddr4:(const struct sockaddr_in *)pSockaddr4
  5384. {
  5385. char addrBuf[INET_ADDRSTRLEN];
  5386. if (inet_ntop(AF_INET, &pSockaddr4->sin_addr, addrBuf, (socklen_t)sizeof(addrBuf)) == NULL)
  5387. {
  5388. addrBuf[0] = '\0';
  5389. }
  5390. return [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding];
  5391. }
  5392. + (NSString *)hostFromSockaddr6:(const struct sockaddr_in6 *)pSockaddr6
  5393. {
  5394. char addrBuf[INET6_ADDRSTRLEN];
  5395. if (inet_ntop(AF_INET6, &pSockaddr6->sin6_addr, addrBuf, (socklen_t)sizeof(addrBuf)) == NULL)
  5396. {
  5397. addrBuf[0] = '\0';
  5398. }
  5399. return [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding];
  5400. }
  5401. + (uint16_t)portFromSockaddr4:(const struct sockaddr_in *)pSockaddr4
  5402. {
  5403. return ntohs(pSockaddr4->sin_port);
  5404. }
  5405. + (uint16_t)portFromSockaddr6:(const struct sockaddr_in6 *)pSockaddr6
  5406. {
  5407. return ntohs(pSockaddr6->sin6_port);
  5408. }
  5409. + (NSString *)hostFromAddress:(NSData *)address
  5410. {
  5411. NSString *host;
  5412. if ([self getHost:&host port:NULL fromAddress:address])
  5413. return host;
  5414. else
  5415. return nil;
  5416. }
  5417. + (uint16_t)portFromAddress:(NSData *)address
  5418. {
  5419. uint16_t port;
  5420. if ([self getHost:NULL port:&port fromAddress:address])
  5421. return port;
  5422. else
  5423. return 0;
  5424. }
  5425. + (BOOL)getHost:(NSString **)hostPtr port:(uint16_t *)portPtr fromAddress:(NSData *)address
  5426. {
  5427. if ([address length] >= sizeof(struct sockaddr))
  5428. {
  5429. const struct sockaddr *sockaddrX = [address bytes];
  5430. if (sockaddrX->sa_family == AF_INET)
  5431. {
  5432. if ([address length] >= sizeof(struct sockaddr_in))
  5433. {
  5434. struct sockaddr_in sockaddr4;
  5435. memcpy(&sockaddr4, sockaddrX, sizeof(sockaddr4));
  5436. if (hostPtr) *hostPtr = [self hostFromSockaddr4:&sockaddr4];
  5437. if (portPtr) *portPtr = [self portFromSockaddr4:&sockaddr4];
  5438. return YES;
  5439. }
  5440. }
  5441. else if (sockaddrX->sa_family == AF_INET6)
  5442. {
  5443. if ([address length] >= sizeof(struct sockaddr_in6))
  5444. {
  5445. struct sockaddr_in6 sockaddr6;
  5446. memcpy(&sockaddr6, sockaddrX, sizeof(sockaddr6));
  5447. if (hostPtr) *hostPtr = [self hostFromSockaddr6:&sockaddr6];
  5448. if (portPtr) *portPtr = [self portFromSockaddr6:&sockaddr6];
  5449. return YES;
  5450. }
  5451. }
  5452. }
  5453. return NO;
  5454. }
  5455. + (NSData *)CRLFData
  5456. {
  5457. return [NSData dataWithBytes:"\x0D\x0A" length:2];
  5458. }
  5459. + (NSData *)CRData
  5460. {
  5461. return [NSData dataWithBytes:"\x0D" length:1];
  5462. }
  5463. + (NSData *)LFData
  5464. {
  5465. return [NSData dataWithBytes:"\x0A" length:1];
  5466. }
  5467. + (NSData *)ZeroData
  5468. {
  5469. return [NSData dataWithBytes:"" length:1];
  5470. }
  5471. @end