mongoose.c 228 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124
  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. // Copyright (c) 2013-2022 Cesanta Software Limited
  3. // All rights reserved
  4. //
  5. // This software is dual-licensed: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License version 2 as
  7. // published by the Free Software Foundation. For the terms of this
  8. // license, see http://www.gnu.org/licenses/
  9. //
  10. // You are free to use this software under the terms of the GNU General
  11. // Public License, but WITHOUT ANY WARRANTY; without even the implied
  12. // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. // See the GNU General Public License for more details.
  14. //
  15. // Alternatively, you can license this software under a commercial
  16. // license, as set out in https://www.mongoose.ws/licensing/
  17. //
  18. // SPDX-License-Identifier: GPL-2.0 or commercial
  19. #include "mongoose.h"
  20. #ifdef MG_ENABLE_LINES
  21. #line 1 "src/base64.c"
  22. #endif
  23. static int mg_b64idx(int c) {
  24. if (c < 26) {
  25. return c + 'A';
  26. } else if (c < 52) {
  27. return c - 26 + 'a';
  28. } else if (c < 62) {
  29. return c - 52 + '0';
  30. } else {
  31. return c == 62 ? '+' : '/';
  32. }
  33. }
  34. static int mg_b64rev(int c) {
  35. if (c >= 'A' && c <= 'Z') {
  36. return c - 'A';
  37. } else if (c >= 'a' && c <= 'z') {
  38. return c + 26 - 'a';
  39. } else if (c >= '0' && c <= '9') {
  40. return c + 52 - '0';
  41. } else if (c == '+') {
  42. return 62;
  43. } else if (c == '/') {
  44. return 63;
  45. } else if (c == '=') {
  46. return 64;
  47. } else {
  48. return -1;
  49. }
  50. }
  51. int mg_base64_update(unsigned char ch, char *to, int n) {
  52. int rem = (n & 3) % 3;
  53. if (rem == 0) {
  54. to[n] = (char) mg_b64idx(ch >> 2);
  55. to[++n] = (char) ((ch & 3) << 4);
  56. } else if (rem == 1) {
  57. to[n] = (char) mg_b64idx(to[n] | (ch >> 4));
  58. to[++n] = (char) ((ch & 15) << 2);
  59. } else {
  60. to[n] = (char) mg_b64idx(to[n] | (ch >> 6));
  61. to[++n] = (char) mg_b64idx(ch & 63);
  62. n++;
  63. }
  64. return n;
  65. }
  66. int mg_base64_final(char *to, int n) {
  67. int saved = n;
  68. // printf("---[%.*s]\n", n, to);
  69. if (n & 3) n = mg_base64_update(0, to, n);
  70. if ((saved & 3) == 2) n--;
  71. // printf(" %d[%.*s]\n", n, n, to);
  72. while (n & 3) to[n++] = '=';
  73. to[n] = '\0';
  74. return n;
  75. }
  76. int mg_base64_encode(const unsigned char *p, int n, char *to) {
  77. int i, len = 0;
  78. for (i = 0; i < n; i++) len = mg_base64_update(p[i], to, len);
  79. len = mg_base64_final(to, len);
  80. return len;
  81. }
  82. int mg_base64_decode(const char *src, int n, char *dst) {
  83. const char *end = src + n;
  84. int len = 0;
  85. while (src + 3 < end) {
  86. int a = mg_b64rev(src[0]), b = mg_b64rev(src[1]), c = mg_b64rev(src[2]),
  87. d = mg_b64rev(src[3]);
  88. if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) return 0;
  89. dst[len++] = (char) ((a << 2) | (b >> 4));
  90. if (src[2] != '=') {
  91. dst[len++] = (char) ((b << 4) | (c >> 2));
  92. if (src[3] != '=') dst[len++] = (char) ((c << 6) | d);
  93. }
  94. src += 4;
  95. }
  96. dst[len] = '\0';
  97. return len;
  98. }
  99. #ifdef MG_ENABLE_LINES
  100. #line 1 "src/dns.c"
  101. #endif
  102. struct dns_data {
  103. struct dns_data *next;
  104. struct mg_connection *c;
  105. uint64_t expire;
  106. uint16_t txnid;
  107. };
  108. static void mg_sendnsreq(struct mg_connection *, struct mg_str *, int,
  109. struct mg_dns *, bool);
  110. static void mg_dns_free(struct mg_connection *c, struct dns_data *d) {
  111. LIST_DELETE(struct dns_data,
  112. (struct dns_data **) &c->mgr->active_dns_requests, d);
  113. free(d);
  114. }
  115. void mg_resolve_cancel(struct mg_connection *c) {
  116. struct dns_data *tmp, *d = (struct dns_data *) c->mgr->active_dns_requests;
  117. for (; d != NULL; d = tmp) {
  118. tmp = d->next;
  119. if (d->c == c) mg_dns_free(c, d);
  120. }
  121. }
  122. static size_t mg_dns_parse_name_depth(const uint8_t *s, size_t len, size_t ofs,
  123. char *to, size_t tolen, size_t j,
  124. int depth) {
  125. size_t i = 0;
  126. if (tolen > 0 && depth == 0) to[0] = '\0';
  127. if (depth > 5) return 0;
  128. // MG_INFO(("ofs %lx %x %x", (unsigned long) ofs, s[ofs], s[ofs + 1]));
  129. while (ofs + i + 1 < len) {
  130. size_t n = s[ofs + i];
  131. if (n == 0) {
  132. i++;
  133. break;
  134. }
  135. if (n & 0xc0) {
  136. size_t ptr = (((n & 0x3f) << 8) | s[ofs + i + 1]); // 12 is hdr len
  137. // MG_INFO(("PTR %lx", (unsigned long) ptr));
  138. if (ptr + 1 < len && (s[ptr] & 0xc0) == 0 &&
  139. mg_dns_parse_name_depth(s, len, ptr, to, tolen, j, depth + 1) == 0)
  140. return 0;
  141. i += 2;
  142. break;
  143. }
  144. if (ofs + i + n + 1 >= len) return 0;
  145. if (j > 0) {
  146. if (j < tolen) to[j] = '.';
  147. j++;
  148. }
  149. if (j + n < tolen) memcpy(&to[j], &s[ofs + i + 1], n);
  150. j += n;
  151. i += n + 1;
  152. if (j < tolen) to[j] = '\0'; // Zero-terminate this chunk
  153. // MG_INFO(("--> [%s]", to));
  154. }
  155. if (tolen > 0) to[tolen - 1] = '\0'; // Make sure make sure it is nul-term
  156. return i;
  157. }
  158. static size_t mg_dns_parse_name(const uint8_t *s, size_t n, size_t ofs,
  159. char *dst, size_t dstlen) {
  160. return mg_dns_parse_name_depth(s, n, ofs, dst, dstlen, 0, 0);
  161. }
  162. size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
  163. bool is_question, struct mg_dns_rr *rr) {
  164. const uint8_t *s = buf + ofs, *e = &buf[len];
  165. memset(rr, 0, sizeof(*rr));
  166. if (len < sizeof(struct mg_dns_header)) return 0; // Too small
  167. if (len > 512) return 0; // Too large, we don't expect that
  168. if (s >= e) return 0; // Overflow
  169. if ((rr->nlen = (uint16_t) mg_dns_parse_name(buf, len, ofs, NULL, 0)) == 0)
  170. return 0;
  171. s += rr->nlen + 4;
  172. if (s > e) return 0;
  173. rr->atype = (uint16_t) (((uint16_t) s[-4] << 8) | s[-3]);
  174. rr->aclass = (uint16_t) (((uint16_t) s[-2] << 8) | s[-1]);
  175. if (is_question) return (size_t) (rr->nlen + 4);
  176. s += 6;
  177. if (s > e) return 0;
  178. rr->alen = (uint16_t) (((uint16_t) s[-2] << 8) | s[-1]);
  179. if (s + rr->alen > e) return 0;
  180. return (size_t) (rr->nlen + rr->alen + 10);
  181. }
  182. bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
  183. const struct mg_dns_header *h = (struct mg_dns_header *) buf;
  184. struct mg_dns_rr rr;
  185. size_t i, n, ofs = sizeof(*h);
  186. memset(dm, 0, sizeof(*dm));
  187. if (len < sizeof(*h)) return 0; // Too small, headers dont fit
  188. if (mg_ntohs(h->num_questions) > 1) return 0; // Sanity
  189. if (mg_ntohs(h->num_answers) > 10) return 0; // Sanity
  190. dm->txnid = mg_ntohs(h->txnid);
  191. for (i = 0; i < mg_ntohs(h->num_questions); i++) {
  192. if ((n = mg_dns_parse_rr(buf, len, ofs, true, &rr)) == 0) return false;
  193. // MG_INFO(("Q %lu %lu %hu/%hu", ofs, n, rr.atype, rr.aclass));
  194. ofs += n;
  195. }
  196. for (i = 0; i < mg_ntohs(h->num_answers); i++) {
  197. if ((n = mg_dns_parse_rr(buf, len, ofs, false, &rr)) == 0) return false;
  198. // MG_INFO(("A -- %lu %lu %hu/%hu %s", ofs, n, rr.atype, rr.aclass,
  199. // dm->name));
  200. mg_dns_parse_name(buf, len, ofs, dm->name, sizeof(dm->name));
  201. ofs += n;
  202. if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) {
  203. dm->addr.is_ip6 = false;
  204. memcpy(&dm->addr.ip, &buf[ofs - 4], 4);
  205. dm->resolved = true;
  206. break; // Return success
  207. } else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) {
  208. dm->addr.is_ip6 = true;
  209. memcpy(&dm->addr.ip6, &buf[ofs - 16], 16);
  210. dm->resolved = true;
  211. break; // Return success
  212. }
  213. }
  214. return true;
  215. }
  216. static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
  217. void *fn_data) {
  218. struct dns_data *d, *tmp;
  219. if (ev == MG_EV_POLL) {
  220. uint64_t now = *(uint64_t *) ev_data;
  221. for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
  222. d = tmp) {
  223. tmp = d->next;
  224. // MG_DEBUG ("%lu %lu dns poll", d->expire, now));
  225. if (now > d->expire) mg_error(d->c, "DNS timeout");
  226. }
  227. } else if (ev == MG_EV_READ) {
  228. struct mg_dns_message dm;
  229. int resolved = 0;
  230. if (mg_dns_parse(c->recv.buf, c->recv.len, &dm) == false) {
  231. MG_ERROR(("Unexpected DNS response:"));
  232. mg_hexdump(c->recv.buf, c->recv.len);
  233. } else {
  234. MG_VERBOSE(("%s %d", dm.name, dm.resolved));
  235. for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
  236. d = tmp) {
  237. tmp = d->next;
  238. // MG_INFO(("d %p %hu %hu", d, d->txnid, dm.txnid));
  239. if (dm.txnid != d->txnid) continue;
  240. if (d->c->is_resolving) {
  241. if (dm.resolved) {
  242. char buf[100];
  243. dm.addr.port = d->c->rem.port; // Save port
  244. d->c->rem = dm.addr; // Copy resolved address
  245. MG_DEBUG(("%lu %s is %s", d->c->id, dm.name,
  246. mg_ntoa(&d->c->rem, buf, sizeof(buf))));
  247. mg_connect_resolved(d->c);
  248. #if MG_ENABLE_IPV6
  249. } else if (dm.addr.is_ip6 == false && dm.name[0] != '\0' &&
  250. c->mgr->use_dns6 == false) {
  251. struct mg_str x = mg_str(dm.name);
  252. mg_sendnsreq(d->c, &x, c->mgr->dnstimeout, &c->mgr->dns6, true);
  253. #endif
  254. } else {
  255. mg_error(d->c, "%s DNS lookup failed", dm.name);
  256. }
  257. } else {
  258. MG_ERROR(("%lu already resolved", d->c->id));
  259. }
  260. mg_dns_free(c, d);
  261. resolved = 1;
  262. }
  263. }
  264. if (!resolved) MG_ERROR(("stray DNS reply"));
  265. c->recv.len = 0;
  266. } else if (ev == MG_EV_CLOSE) {
  267. for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
  268. d = tmp) {
  269. tmp = d->next;
  270. mg_error(d->c, "DNS error");
  271. mg_dns_free(c, d);
  272. }
  273. }
  274. (void) fn_data;
  275. }
  276. static bool mg_dns_send(struct mg_connection *c, const struct mg_str *name,
  277. uint16_t txnid, bool ipv6) {
  278. struct {
  279. struct mg_dns_header header;
  280. uint8_t data[256];
  281. } pkt;
  282. size_t i, n;
  283. memset(&pkt, 0, sizeof(pkt));
  284. pkt.header.txnid = mg_htons(txnid);
  285. pkt.header.flags = mg_htons(0x100);
  286. pkt.header.num_questions = mg_htons(1);
  287. for (i = n = 0; i < sizeof(pkt.data) - 5; i++) {
  288. if (name->ptr[i] == '.' || i >= name->len) {
  289. pkt.data[n] = (uint8_t) (i - n);
  290. memcpy(&pkt.data[n + 1], name->ptr + n, i - n);
  291. n = i + 1;
  292. }
  293. if (i >= name->len) break;
  294. }
  295. memcpy(&pkt.data[n], "\x00\x00\x01\x00\x01", 5); // A query
  296. n += 5;
  297. if (ipv6) pkt.data[n - 3] = 0x1c; // AAAA query
  298. // memcpy(&pkt.data[n], "\xc0\x0c\x00\x1c\x00\x01", 6); // AAAA query
  299. // n += 6;
  300. return mg_send(c, &pkt, sizeof(pkt.header) + n);
  301. }
  302. static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
  303. struct mg_dns *dnsc, bool ipv6) {
  304. struct dns_data *d = NULL;
  305. if (dnsc->url == NULL) {
  306. mg_error(c, "DNS server URL is NULL. Call mg_mgr_init()");
  307. } else if (dnsc->c == NULL) {
  308. dnsc->c = mg_connect(c->mgr, dnsc->url, NULL, NULL);
  309. if (dnsc->c != NULL) {
  310. dnsc->c->pfn = dns_cb;
  311. // dnsc->c->is_hexdumping = 1;
  312. }
  313. }
  314. if (dnsc->c == NULL) {
  315. mg_error(c, "resolver");
  316. } else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) {
  317. mg_error(c, "resolve OOM");
  318. } else {
  319. struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests;
  320. char buf[100];
  321. d->txnid = reqs ? (uint16_t) (reqs->txnid + 1) : 1;
  322. d->next = (struct dns_data *) c->mgr->active_dns_requests;
  323. c->mgr->active_dns_requests = d;
  324. d->expire = mg_millis() + (uint64_t) ms;
  325. d->c = c;
  326. c->is_resolving = 1;
  327. MG_VERBOSE(("%lu resolving %.*s @ %s, txnid %hu", c->id, (int) name->len,
  328. name->ptr, mg_ntoa(&dnsc->c->rem, buf, sizeof(buf)), d->txnid));
  329. if (!mg_dns_send(dnsc->c, name, d->txnid, ipv6)) {
  330. mg_error(dnsc->c, "DNS send");
  331. }
  332. }
  333. }
  334. void mg_resolve(struct mg_connection *c, const char *url) {
  335. struct mg_str host = mg_url_host(url);
  336. c->rem.port = mg_htons(mg_url_port(url));
  337. if (mg_aton(host, &c->rem)) {
  338. // host is an IP address, do not fire name resolution
  339. mg_connect_resolved(c);
  340. } else {
  341. // host is not an IP, send DNS resolution request
  342. struct mg_dns *dns = c->mgr->use_dns6 ? &c->mgr->dns6 : &c->mgr->dns4;
  343. mg_sendnsreq(c, &host, c->mgr->dnstimeout, dns, c->mgr->use_dns6);
  344. }
  345. }
  346. #ifdef MG_ENABLE_LINES
  347. #line 1 "src/event.c"
  348. #endif
  349. void mg_call(struct mg_connection *c, int ev, void *ev_data) {
  350. // Run user-defined handler first, in order to give it an ability
  351. // to intercept processing (e.g. clean input buffer) before the
  352. // protocol handler kicks in
  353. if (c->fn != NULL) c->fn(c, ev, ev_data, c->fn_data);
  354. if (c->pfn != NULL) c->pfn(c, ev, ev_data, c->pfn_data);
  355. }
  356. void mg_error(struct mg_connection *c, const char *fmt, ...) {
  357. char buf[64];
  358. va_list ap;
  359. va_start(ap, fmt);
  360. mg_vsnprintf(buf, sizeof(buf), fmt, &ap);
  361. va_end(ap);
  362. MG_ERROR(("%lu %p %s", c->id, c->fd, buf));
  363. c->is_closing = 1; // Set is_closing before sending MG_EV_CALL
  364. mg_call(c, MG_EV_ERROR, buf); // Let user handler to override it
  365. }
  366. #ifdef MG_ENABLE_LINES
  367. #line 1 "src/fmt.c"
  368. #endif
  369. static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
  370. struct mg_iobuf *io = (struct mg_iobuf *) param;
  371. if (expand && io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
  372. if (io->len + 2 <= io->size) {
  373. io->buf[io->len++] = (uint8_t) ch;
  374. io->buf[io->len] = 0;
  375. } else if (io->len < io->size) {
  376. io->buf[io->len++] = 0; // Guarantee to 0-terminate
  377. }
  378. }
  379. static void mg_putchar_iobuf_static(char ch, void *param) {
  380. mg_pfn_iobuf_private(ch, param, false);
  381. }
  382. void mg_pfn_iobuf(char ch, void *param) {
  383. mg_pfn_iobuf_private(ch, param, true);
  384. }
  385. size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
  386. struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
  387. size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
  388. if (n < len) buf[n] = '\0';
  389. return n;
  390. }
  391. size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
  392. va_list ap;
  393. size_t n;
  394. va_start(ap, fmt);
  395. n = mg_vsnprintf(buf, len, fmt, &ap);
  396. va_end(ap);
  397. return n;
  398. }
  399. char *mg_vmprintf(const char *fmt, va_list *ap) {
  400. struct mg_iobuf io = {0, 0, 0, 256};
  401. mg_vxprintf(mg_pfn_iobuf, &io, fmt, ap);
  402. return (char *) io.buf;
  403. }
  404. char *mg_mprintf(const char *fmt, ...) {
  405. char *s;
  406. va_list ap;
  407. va_start(ap, fmt);
  408. s = mg_vmprintf(fmt, &ap);
  409. va_end(ap);
  410. return s;
  411. }
  412. size_t mg_xprintf(void (*out)(char, void *), void *ptr, const char *fmt, ...) {
  413. size_t len = 0;
  414. va_list ap;
  415. va_start(ap, fmt);
  416. len = mg_vxprintf(out, ptr, fmt, &ap);
  417. va_end(ap);
  418. return len;
  419. }
  420. static bool is_digit(int c) {
  421. return c >= '0' && c <= '9';
  422. }
  423. static int addexp(char *buf, int e, int sign) {
  424. int n = 0;
  425. buf[n++] = 'e';
  426. buf[n++] = (char) sign;
  427. if (e > 400) return 0;
  428. if (e < 10) buf[n++] = '0';
  429. if (e >= 100) buf[n++] = (char) (e / 100 + '0'), e -= 100 * (e / 100);
  430. if (e >= 10) buf[n++] = (char) (e / 10 + '0'), e -= 10 * (e / 10);
  431. buf[n++] = (char) (e + '0');
  432. return n;
  433. }
  434. static int xisinf(double x) {
  435. union {
  436. double f;
  437. uint64_t u;
  438. } ieee754 = {x};
  439. return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
  440. ((unsigned) ieee754.u == 0);
  441. }
  442. static int xisnan(double x) {
  443. union {
  444. double f;
  445. uint64_t u;
  446. } ieee754 = {x};
  447. return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
  448. ((unsigned) ieee754.u != 0) >
  449. 0x7ff00000;
  450. }
  451. static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
  452. char buf[40];
  453. int i, s = 0, n = 0, e = 0;
  454. double t, mul, saved;
  455. if (d == 0.0) return mg_snprintf(dst, dstlen, "%s", "0");
  456. if (xisinf(d)) return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf");
  457. if (xisnan(d)) return mg_snprintf(dst, dstlen, "%s", "nan");
  458. if (d < 0.0) d = -d, buf[s++] = '-';
  459. // Round
  460. saved = d;
  461. mul = 1.0;
  462. while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0;
  463. while (d <= 1.0 && d / mul <= 1.0) mul /= 10.0;
  464. for (i = 0, t = mul * 5; i < width; i++) t /= 10.0;
  465. d += t;
  466. // Calculate exponent, and 'mul' for scientific representation
  467. mul = 1.0;
  468. while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0, e++;
  469. while (d < 1.0 && d / mul < 1.0) mul /= 10.0, e--;
  470. // printf(" --> %g %d %g %g\n", saved, e, t, mul);
  471. if (e >= width) {
  472. n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width);
  473. // printf(" --> %.*g %d [%.*s]\n", 10, d / t, e, n, buf);
  474. n += addexp(buf + s + n, e, '+');
  475. return mg_snprintf(dst, dstlen, "%.*s", n, buf);
  476. } else if (e <= -width) {
  477. n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width);
  478. // printf(" --> %.*g %d [%.*s]\n", 10, d / mul, e, n, buf);
  479. n += addexp(buf + s + n, -e, '-');
  480. return mg_snprintf(dst, dstlen, "%.*s", n, buf);
  481. } else {
  482. for (i = 0, t = mul; t >= 1.0 && s + n < (int) sizeof(buf); i++) {
  483. int ch = (int) (d / t);
  484. if (n > 0 || ch > 0) buf[s + n++] = (char) (ch + '0');
  485. d -= ch * t;
  486. t /= 10.0;
  487. }
  488. // printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf);
  489. if (n == 0) buf[s++] = '0';
  490. while (t >= 1.0 && n + s < (int) sizeof(buf)) buf[n++] = '0', t /= 10.0;
  491. if (s + n < (int) sizeof(buf)) buf[n + s++] = '.';
  492. // printf(" 1--> [%g] -> [%.*s]\n", saved, s + n, buf);
  493. for (i = 0, t = 0.1; s + n < (int) sizeof(buf) && n < width; i++) {
  494. int ch = (int) (d / t);
  495. buf[s + n++] = (char) (ch + '0');
  496. d -= ch * t;
  497. t /= 10.0;
  498. }
  499. }
  500. while (n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeros
  501. if (n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
  502. buf[s + n] = '\0';
  503. return mg_snprintf(dst, dstlen, "%s", buf);
  504. }
  505. static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
  506. const char *letters = "0123456789abcdef";
  507. uint64_t v = (uint64_t) val;
  508. size_t s = 0, n, i;
  509. if (is_signed && val < 0) buf[s++] = '-', v = (uint64_t) (-val);
  510. // This loop prints a number in reverse order. I guess this is because we
  511. // write numbers from right to left: least significant digit comes last.
  512. // Maybe because we use Arabic numbers, and Arabs write RTL?
  513. if (is_hex) {
  514. for (n = 0; v; v >>= 4) buf[s + n++] = letters[v & 15];
  515. } else {
  516. for (n = 0; v; v /= 10) buf[s + n++] = letters[v % 10];
  517. }
  518. // Reverse a string
  519. for (i = 0; i < n / 2; i++) {
  520. char t = buf[s + i];
  521. buf[s + i] = buf[s + n - i - 1], buf[s + n - i - 1] = t;
  522. }
  523. if (val == 0) buf[n++] = '0'; // Handle special case
  524. return n + s;
  525. }
  526. static size_t scpy(void (*out)(char, void *), void *ptr, char *buf,
  527. size_t len) {
  528. size_t i = 0;
  529. while (i < len && buf[i] != '\0') out(buf[i++], ptr);
  530. return i;
  531. }
  532. static char mg_esc(int c, bool esc) {
  533. const char *p, *esc1 = "\b\f\n\r\t\\\"", *esc2 = "bfnrt\\\"";
  534. for (p = esc ? esc1 : esc2; *p != '\0'; p++) {
  535. if (*p == c) return esc ? esc2[p - esc1] : esc1[p - esc2];
  536. }
  537. return 0;
  538. }
  539. static char mg_escape(int c) {
  540. return mg_esc(c, true);
  541. }
  542. static size_t qcpy(void (*out)(char, void *), void *ptr, char *buf,
  543. size_t len) {
  544. size_t i = 0, extra = 0;
  545. for (i = 0; i < len && buf[i] != '\0'; i++) {
  546. char c = mg_escape(buf[i]);
  547. if (c) {
  548. out('\\', ptr), out(c, ptr), extra++;
  549. } else {
  550. out(buf[i], ptr);
  551. }
  552. }
  553. return i + extra;
  554. }
  555. static size_t Qcpy(void (*out)(char, void *), void *ptr, char *buf,
  556. size_t len) {
  557. size_t n = 2;
  558. out('"', ptr);
  559. n += qcpy(out, ptr, buf, len);
  560. out('"', ptr);
  561. return n;
  562. }
  563. static size_t bcpy(void (*out)(char, void *), void *ptr, uint8_t *buf,
  564. size_t len) {
  565. size_t i, n = 0;
  566. const char *t =
  567. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  568. out('"', ptr), n++;
  569. for (i = 0; i < len; i += 3) {
  570. uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0,
  571. c3 = i + 2 < len ? buf[i + 2] : 0;
  572. char tmp[4] = {t[c1 >> 2], t[(c1 & 3) << 4 | (c2 >> 4)], '=', '='};
  573. if (i + 1 < len) tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)];
  574. if (i + 2 < len) tmp[3] = t[c3 & 63];
  575. n += scpy(out, ptr, tmp, sizeof(tmp));
  576. }
  577. out('"', ptr), n++;
  578. return n;
  579. }
  580. size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
  581. va_list *ap) {
  582. size_t i = 0, n = 0;
  583. while (fmt[i] != '\0') {
  584. if (fmt[i] == '%') {
  585. size_t j, k, x = 0, is_long = 0, w = 0 /* width */, pr = ~0U /* prec */;
  586. char pad = ' ', minus = 0, c = fmt[++i];
  587. if (c == '#') x++, c = fmt[++i];
  588. if (c == '-') minus++, c = fmt[++i];
  589. if (c == '0') pad = '0', c = fmt[++i];
  590. while (is_digit(c)) w *= 10, w += (size_t) (c - '0'), c = fmt[++i];
  591. if (c == '.') {
  592. c = fmt[++i];
  593. if (c == '*') {
  594. pr = (size_t) va_arg(*ap, int);
  595. c = fmt[++i];
  596. } else {
  597. pr = 0;
  598. while (is_digit(c)) pr *= 10, pr += (size_t) (c - '0'), c = fmt[++i];
  599. }
  600. }
  601. while (c == 'h') c = fmt[++i]; // Treat h and hh as int
  602. if (c == 'l') {
  603. is_long++, c = fmt[++i];
  604. if (c == 'l') is_long++, c = fmt[++i];
  605. }
  606. if (c == 'p') x = 1, is_long = 1;
  607. if (c == 'd' || c == 'u' || c == 'x' || c == 'X' || c == 'p' ||
  608. c == 'g') {
  609. bool s = (c == 'd'), h = (c == 'x' || c == 'X' || c == 'p');
  610. char tmp[40];
  611. size_t xl = x ? 2 : 0;
  612. if (c == 'g' || c == 'f') {
  613. double v = va_arg(*ap, double);
  614. if (pr == ~0U) pr = 6;
  615. k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr);
  616. } else if (is_long == 2) {
  617. int64_t v = va_arg(*ap, int64_t);
  618. k = mg_lld(tmp, v, s, h);
  619. } else if (is_long == 1) {
  620. long v = va_arg(*ap, long);
  621. k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned long) v, s, h);
  622. } else {
  623. int v = va_arg(*ap, int);
  624. k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned) v, s, h);
  625. }
  626. for (j = 0; j < xl && w > 0; j++) w--;
  627. for (j = 0; pad == ' ' && !minus && k < w && j + k < w; j++)
  628. n += scpy(out, param, &pad, 1);
  629. n += scpy(out, param, (char *) "0x", xl);
  630. for (j = 0; pad == '0' && k < w && j + k < w; j++)
  631. n += scpy(out, param, &pad, 1);
  632. n += scpy(out, param, tmp, k);
  633. for (j = 0; pad == ' ' && minus && k < w && j + k < w; j++)
  634. n += scpy(out, param, &pad, 1);
  635. } else if (c == 'M') {
  636. mg_pm_t f = va_arg(*ap, mg_pm_t);
  637. n += f(out, param, ap);
  638. } else if (c == 'c') {
  639. int ch = va_arg(*ap, int);
  640. out((char) ch, param);
  641. n++;
  642. } else if (c == 'H') {
  643. // Print hex-encoded double-quoted string
  644. size_t bl = (size_t) va_arg(*ap, int);
  645. uint8_t *p = va_arg(*ap, uint8_t *), dquote = '"';
  646. const char *hex = "0123456789abcdef";
  647. n += scpy(out, param, (char *) &dquote, 1);
  648. for (j = 0; j < bl; j++) {
  649. n += scpy(out, param, (char *) &hex[(p[j] >> 4) & 15], 1);
  650. n += scpy(out, param, (char *) &hex[p[j] & 15], 1);
  651. }
  652. n += scpy(out, param, (char *) &dquote, 1);
  653. } else if (c == 'V') {
  654. // Print base64-encoded double-quoted string
  655. size_t len = (size_t) va_arg(*ap, int);
  656. uint8_t *buf = va_arg(*ap, uint8_t *);
  657. n += bcpy(out, param, buf, len);
  658. } else if (c == 's' || c == 'Q' || c == 'q') {
  659. char *p = va_arg(*ap, char *);
  660. size_t (*f)(void (*)(char, void *), void *, char *, size_t) = scpy;
  661. if (c == 'Q') f = Qcpy;
  662. if (c == 'q') f = qcpy;
  663. if (pr == ~0U) pr = p == NULL ? 0 : strlen(p);
  664. for (j = 0; !minus && pr < w && j + pr < w; j++)
  665. n += f(out, param, &pad, 1);
  666. n += f(out, param, p, pr);
  667. for (j = 0; minus && pr < w && j + pr < w; j++)
  668. n += f(out, param, &pad, 1);
  669. } else if (c == '%') {
  670. out('%', param);
  671. n++;
  672. } else {
  673. out('%', param);
  674. out(c, param);
  675. n += 2;
  676. }
  677. i++;
  678. } else {
  679. out(fmt[i], param), n++, i++;
  680. }
  681. }
  682. return n;
  683. }
  684. #ifdef MG_ENABLE_LINES
  685. #line 1 "src/fs.c"
  686. #endif
  687. struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) {
  688. struct mg_fd *fd = (struct mg_fd *) calloc(1, sizeof(*fd));
  689. if (fd != NULL) {
  690. fd->fd = fs->op(path, flags);
  691. fd->fs = fs;
  692. if (fd->fd == NULL) {
  693. free(fd);
  694. fd = NULL;
  695. }
  696. }
  697. return fd;
  698. }
  699. void mg_fs_close(struct mg_fd *fd) {
  700. if (fd != NULL) {
  701. fd->fs->cl(fd->fd);
  702. free(fd);
  703. }
  704. }
  705. char *mg_file_read(struct mg_fs *fs, const char *path, size_t *sizep) {
  706. struct mg_fd *fd;
  707. char *data = NULL;
  708. size_t size = 0;
  709. fs->st(path, &size, NULL);
  710. if ((fd = mg_fs_open(fs, path, MG_FS_READ)) != NULL) {
  711. data = (char *) calloc(1, size + 1);
  712. if (data != NULL) {
  713. if (fs->rd(fd->fd, data, size) != size) {
  714. free(data);
  715. data = NULL;
  716. } else {
  717. data[size] = '\0';
  718. if (sizep != NULL) *sizep = size;
  719. }
  720. }
  721. mg_fs_close(fd);
  722. }
  723. return data;
  724. }
  725. bool mg_file_write(struct mg_fs *fs, const char *path, const void *buf,
  726. size_t len) {
  727. bool result = false;
  728. struct mg_fd *fd;
  729. char tmp[MG_PATH_MAX];
  730. mg_snprintf(tmp, sizeof(tmp), "%s..%d", path, rand());
  731. if ((fd = mg_fs_open(fs, tmp, MG_FS_WRITE)) != NULL) {
  732. result = fs->wr(fd->fd, buf, len) == len;
  733. mg_fs_close(fd);
  734. if (result) {
  735. fs->rm(path);
  736. fs->mv(tmp, path);
  737. } else {
  738. fs->rm(tmp);
  739. }
  740. }
  741. return result;
  742. }
  743. bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...) {
  744. va_list ap;
  745. char *data;
  746. bool result = false;
  747. va_start(ap, fmt);
  748. data = mg_vmprintf(fmt, &ap);
  749. va_end(ap);
  750. result = mg_file_write(fs, path, data, strlen(data));
  751. free(data);
  752. return result;
  753. }
  754. #ifdef MG_ENABLE_LINES
  755. #line 1 "src/fs_fat.c"
  756. #endif
  757. #if MG_ENABLE_FATFS
  758. #include <ff.h>
  759. static int mg_days_from_epoch(int y, int m, int d) {
  760. y -= m <= 2;
  761. int era = y / 400;
  762. int yoe = y - era * 400;
  763. int doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1;
  764. int doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
  765. return era * 146097 + doe - 719468;
  766. }
  767. static time_t mg_timegm(const struct tm *t) {
  768. int year = t->tm_year + 1900;
  769. int month = t->tm_mon; // 0-11
  770. if (month > 11) {
  771. year += month / 12;
  772. month %= 12;
  773. } else if (month < 0) {
  774. int years_diff = (11 - month) / 12;
  775. year -= years_diff;
  776. month += 12 * years_diff;
  777. }
  778. int x = mg_days_from_epoch(year, month + 1, t->tm_mday);
  779. return 60 * (60 * (24L * x + t->tm_hour) + t->tm_min) + t->tm_sec;
  780. }
  781. static time_t ff_time_to_epoch(uint16_t fdate, uint16_t ftime) {
  782. struct tm tm;
  783. memset(&tm, 0, sizeof(struct tm));
  784. tm.tm_sec = (ftime << 1) & 0x3e;
  785. tm.tm_min = ((ftime >> 5) & 0x3f);
  786. tm.tm_hour = ((ftime >> 11) & 0x1f);
  787. tm.tm_mday = (fdate & 0x1f);
  788. tm.tm_mon = ((fdate >> 5) & 0x0f) - 1;
  789. tm.tm_year = ((fdate >> 9) & 0x7f) + 80;
  790. return mg_timegm(&tm);
  791. }
  792. static int ff_stat(const char *path, size_t *size, time_t *mtime) {
  793. FILINFO fi;
  794. if (path[0] == '\0') {
  795. if (size) *size = 0;
  796. if (mtime) *mtime = 0;
  797. return MG_FS_DIR;
  798. } else if (f_stat(path, &fi) == 0) {
  799. if (size) *size = (size_t) fi.fsize;
  800. if (mtime) *mtime = ff_time_to_epoch(fi.fdate, fi.ftime);
  801. return MG_FS_READ | MG_FS_WRITE | ((fi.fattrib & AM_DIR) ? MG_FS_DIR : 0);
  802. } else {
  803. return 0;
  804. }
  805. }
  806. static void ff_list(const char *dir, void (*fn)(const char *, void *),
  807. void *userdata) {
  808. DIR d;
  809. FILINFO fi;
  810. if (f_opendir(&d, dir) == FR_OK) {
  811. while (f_readdir(&d, &fi) == FR_OK && fi.fname[0] != '\0') {
  812. if (!strcmp(fi.fname, ".") || !strcmp(fi.fname, "..")) continue;
  813. fn(fi.fname, userdata);
  814. }
  815. f_closedir(&d);
  816. }
  817. }
  818. static void *ff_open(const char *path, int flags) {
  819. FIL f;
  820. unsigned char mode = FA_READ;
  821. if (flags & MG_FS_WRITE) mode |= FA_WRITE | FA_OPEN_ALWAYS | FA_OPEN_APPEND;
  822. if (f_open(&f, path, mode) == 0) {
  823. FIL *fp = calloc(1, sizeof(*fp));
  824. memcpy(fp, &f, sizeof(*fp));
  825. return fp;
  826. } else {
  827. return NULL;
  828. }
  829. }
  830. static void ff_close(void *fp) {
  831. if (fp != NULL) {
  832. f_close((FIL *) fp);
  833. free(fp);
  834. }
  835. }
  836. static size_t ff_read(void *fp, void *buf, size_t len) {
  837. UINT n = 0, misalign = ((size_t) buf) & 3;
  838. if (misalign) {
  839. char aligned[4];
  840. f_read((FIL *) fp, aligned, len > misalign ? misalign : len, &n);
  841. memcpy(buf, aligned, n);
  842. } else {
  843. f_read((FIL *) fp, buf, len, &n);
  844. }
  845. return n;
  846. }
  847. static size_t ff_write(void *fp, const void *buf, size_t len) {
  848. UINT n = 0;
  849. return f_write((FIL *) fp, (char *) buf, len, &n) == FR_OK ? n : 0;
  850. }
  851. static size_t ff_seek(void *fp, size_t offset) {
  852. f_lseek((FIL *) fp, offset);
  853. return offset;
  854. }
  855. static bool ff_rename(const char *from, const char *to) {
  856. return f_rename(from, to) == FR_OK;
  857. }
  858. static bool ff_remove(const char *path) {
  859. return f_unlink(path) == FR_OK;
  860. }
  861. static bool ff_mkdir(const char *path) {
  862. return f_mkdir(path) == FR_OK;
  863. }
  864. struct mg_fs mg_fs_fat = {ff_stat, ff_list, ff_open, ff_close, ff_read,
  865. ff_write, ff_seek, ff_rename, ff_remove, ff_mkdir};
  866. #endif
  867. #ifdef MG_ENABLE_LINES
  868. #line 1 "src/fs_packed.c"
  869. #endif
  870. struct packed_file {
  871. const char *data;
  872. size_t size;
  873. size_t pos;
  874. };
  875. const char *mg_unpack(const char *path, size_t *size, time_t *mtime);
  876. const char *mg_unlist(size_t no);
  877. #if MG_ENABLE_PACKED_FS
  878. #else
  879. const char *mg_unpack(const char *path, size_t *size, time_t *mtime) {
  880. (void) path, (void) size, (void) mtime;
  881. return NULL;
  882. }
  883. const char *mg_unlist(size_t no) {
  884. (void) no;
  885. return NULL;
  886. }
  887. #endif
  888. static int is_dir_prefix(const char *prefix, size_t n, const char *path) {
  889. // MG_INFO(("[%.*s] [%s] %c", (int) n, prefix, path, path[n]));
  890. return n < strlen(path) && strncmp(prefix, path, n) == 0 &&
  891. (n == 0 || path[n] == '/' || path[n - 1] == '/');
  892. }
  893. static int packed_stat(const char *path, size_t *size, time_t *mtime) {
  894. const char *p;
  895. size_t i, n = strlen(path);
  896. if (mg_unpack(path, size, mtime)) return MG_FS_READ; // Regular file
  897. // Scan all files. If `path` is a dir prefix for any of them, it's a dir
  898. for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
  899. if (is_dir_prefix(path, n, p)) return MG_FS_DIR;
  900. }
  901. return 0;
  902. }
  903. static void packed_list(const char *dir, void (*fn)(const char *, void *),
  904. void *userdata) {
  905. char buf[MG_PATH_MAX], tmp[sizeof(buf)];
  906. const char *path, *begin, *end;
  907. size_t i, n = strlen(dir);
  908. tmp[0] = '\0'; // Previously listed entry
  909. for (i = 0; (path = mg_unlist(i)) != NULL; i++) {
  910. if (!is_dir_prefix(dir, n, path)) continue;
  911. begin = &path[n + 1];
  912. end = strchr(begin, '/');
  913. if (end == NULL) end = begin + strlen(begin);
  914. mg_snprintf(buf, sizeof(buf), "%.*s", (int) (end - begin), begin);
  915. buf[sizeof(buf) - 1] = '\0';
  916. // If this entry has been already listed, skip
  917. // NOTE: we're assuming that file list is sorted alphabetically
  918. if (strcmp(buf, tmp) == 0) continue;
  919. fn(buf, userdata); // Not yet listed, call user function
  920. strcpy(tmp, buf); // And save this entry as listed
  921. }
  922. }
  923. static void *packed_open(const char *path, int flags) {
  924. size_t size = 0;
  925. const char *data = mg_unpack(path, &size, NULL);
  926. struct packed_file *fp = NULL;
  927. if (data == NULL) return NULL;
  928. if (flags & MG_FS_WRITE) return NULL;
  929. fp = (struct packed_file *) calloc(1, sizeof(*fp));
  930. fp->size = size;
  931. fp->data = data;
  932. return (void *) fp;
  933. }
  934. static void packed_close(void *fp) {
  935. if (fp != NULL) free(fp);
  936. }
  937. static size_t packed_read(void *fd, void *buf, size_t len) {
  938. struct packed_file *fp = (struct packed_file *) fd;
  939. if (fp->pos + len > fp->size) len = fp->size - fp->pos;
  940. memcpy(buf, &fp->data[fp->pos], len);
  941. fp->pos += len;
  942. return len;
  943. }
  944. static size_t packed_write(void *fd, const void *buf, size_t len) {
  945. (void) fd, (void) buf, (void) len;
  946. return 0;
  947. }
  948. static size_t packed_seek(void *fd, size_t offset) {
  949. struct packed_file *fp = (struct packed_file *) fd;
  950. fp->pos = offset;
  951. if (fp->pos > fp->size) fp->pos = fp->size;
  952. return fp->pos;
  953. }
  954. static bool packed_rename(const char *from, const char *to) {
  955. (void) from, (void) to;
  956. return false;
  957. }
  958. static bool packed_remove(const char *path) {
  959. (void) path;
  960. return false;
  961. }
  962. static bool packed_mkdir(const char *path) {
  963. (void) path;
  964. return false;
  965. }
  966. struct mg_fs mg_fs_packed = {
  967. packed_stat, packed_list, packed_open, packed_close, packed_read,
  968. packed_write, packed_seek, packed_rename, packed_remove, packed_mkdir};
  969. #ifdef MG_ENABLE_LINES
  970. #line 1 "src/fs_posix.c"
  971. #endif
  972. #if MG_ENABLE_FILE
  973. #ifndef MG_STAT_STRUCT
  974. #define MG_STAT_STRUCT stat
  975. #endif
  976. #ifndef MG_STAT_FUNC
  977. #define MG_STAT_FUNC stat
  978. #endif
  979. static int p_stat(const char *path, size_t *size, time_t *mtime) {
  980. #if !defined(S_ISDIR)
  981. MG_ERROR(("stat() API is not supported. %p %p %p", path, size, mtime));
  982. return 0;
  983. #else
  984. #if MG_ARCH == MG_ARCH_WIN32
  985. struct _stati64 st;
  986. wchar_t tmp[MG_PATH_MAX];
  987. MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
  988. if (_wstati64(tmp, &st) != 0) return 0;
  989. #else
  990. struct MG_STAT_STRUCT st;
  991. if (MG_STAT_FUNC(path, &st) != 0) return 0;
  992. #endif
  993. if (size) *size = (size_t) st.st_size;
  994. if (mtime) *mtime = st.st_mtime;
  995. return MG_FS_READ | MG_FS_WRITE | (S_ISDIR(st.st_mode) ? MG_FS_DIR : 0);
  996. #endif
  997. }
  998. #if MG_ARCH == MG_ARCH_WIN32
  999. struct dirent {
  1000. char d_name[MAX_PATH];
  1001. };
  1002. typedef struct win32_dir {
  1003. HANDLE handle;
  1004. WIN32_FIND_DATAW info;
  1005. struct dirent result;
  1006. } DIR;
  1007. int gettimeofday(struct timeval *tv, void *tz) {
  1008. FILETIME ft;
  1009. unsigned __int64 tmpres = 0;
  1010. if (tv != NULL) {
  1011. GetSystemTimeAsFileTime(&ft);
  1012. tmpres |= ft.dwHighDateTime;
  1013. tmpres <<= 32;
  1014. tmpres |= ft.dwLowDateTime;
  1015. tmpres /= 10; // convert into microseconds
  1016. tmpres -= (int64_t) 11644473600000000;
  1017. tv->tv_sec = (long) (tmpres / 1000000UL);
  1018. tv->tv_usec = (long) (tmpres % 1000000UL);
  1019. }
  1020. (void) tz;
  1021. return 0;
  1022. }
  1023. static int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
  1024. int ret;
  1025. char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
  1026. strncpy(buf, path, sizeof(buf));
  1027. buf[sizeof(buf) - 1] = '\0';
  1028. // Trim trailing slashes. Leave backslash for paths like "X:\"
  1029. p = buf + strlen(buf) - 1;
  1030. while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
  1031. memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
  1032. ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
  1033. // Convert back to Unicode. If doubly-converted string does not match the
  1034. // original, something is fishy, reject.
  1035. WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
  1036. NULL, NULL);
  1037. if (strcmp(buf, buf2) != 0) {
  1038. wbuf[0] = L'\0';
  1039. ret = 0;
  1040. }
  1041. return ret;
  1042. }
  1043. DIR *opendir(const char *name) {
  1044. DIR *d = NULL;
  1045. wchar_t wpath[MAX_PATH];
  1046. DWORD attrs;
  1047. if (name == NULL) {
  1048. SetLastError(ERROR_BAD_ARGUMENTS);
  1049. } else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) {
  1050. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1051. } else {
  1052. to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0]));
  1053. attrs = GetFileAttributesW(wpath);
  1054. if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
  1055. (void) wcscat(wpath, L"\\*");
  1056. d->handle = FindFirstFileW(wpath, &d->info);
  1057. d->result.d_name[0] = '\0';
  1058. } else {
  1059. free(d);
  1060. d = NULL;
  1061. }
  1062. }
  1063. return d;
  1064. }
  1065. int closedir(DIR *d) {
  1066. int result = 0;
  1067. if (d != NULL) {
  1068. if (d->handle != INVALID_HANDLE_VALUE)
  1069. result = FindClose(d->handle) ? 0 : -1;
  1070. free(d);
  1071. } else {
  1072. result = -1;
  1073. SetLastError(ERROR_BAD_ARGUMENTS);
  1074. }
  1075. return result;
  1076. }
  1077. struct dirent *readdir(DIR *d) {
  1078. struct dirent *result = NULL;
  1079. if (d != NULL) {
  1080. memset(&d->result, 0, sizeof(d->result));
  1081. if (d->handle != INVALID_HANDLE_VALUE) {
  1082. result = &d->result;
  1083. WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name,
  1084. sizeof(result->d_name), NULL, NULL);
  1085. if (!FindNextFileW(d->handle, &d->info)) {
  1086. FindClose(d->handle);
  1087. d->handle = INVALID_HANDLE_VALUE;
  1088. }
  1089. } else {
  1090. SetLastError(ERROR_FILE_NOT_FOUND);
  1091. }
  1092. } else {
  1093. SetLastError(ERROR_BAD_ARGUMENTS);
  1094. }
  1095. return result;
  1096. }
  1097. #endif
  1098. static void p_list(const char *dir, void (*fn)(const char *, void *),
  1099. void *userdata) {
  1100. #if MG_ENABLE_DIRLIST
  1101. struct dirent *dp;
  1102. DIR *dirp;
  1103. if ((dirp = (opendir(dir))) == NULL) return;
  1104. while ((dp = readdir(dirp)) != NULL) {
  1105. if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
  1106. fn(dp->d_name, userdata);
  1107. }
  1108. closedir(dirp);
  1109. #else
  1110. (void) dir, (void) fn, (void) userdata;
  1111. #endif
  1112. }
  1113. static void *p_open(const char *path, int flags) {
  1114. const char *mode = flags == MG_FS_READ ? "rb" : "a+b";
  1115. #if MG_ARCH == MG_ARCH_WIN32
  1116. wchar_t b1[MG_PATH_MAX], b2[10];
  1117. MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
  1118. MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
  1119. return (void *) _wfopen(b1, b2);
  1120. #else
  1121. return (void *) fopen(path, mode);
  1122. #endif
  1123. }
  1124. static void p_close(void *fp) {
  1125. fclose((FILE *) fp);
  1126. }
  1127. static size_t p_read(void *fp, void *buf, size_t len) {
  1128. return fread(buf, 1, len, (FILE *) fp);
  1129. }
  1130. static size_t p_write(void *fp, const void *buf, size_t len) {
  1131. return fwrite(buf, 1, len, (FILE *) fp);
  1132. }
  1133. static size_t p_seek(void *fp, size_t offset) {
  1134. #if (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) || \
  1135. (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
  1136. (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
  1137. if (fseeko((FILE *) fp, (off_t) offset, SEEK_SET) != 0) (void) 0;
  1138. #else
  1139. if (fseek((FILE *) fp, (long) offset, SEEK_SET) != 0) (void) 0;
  1140. #endif
  1141. return (size_t) ftell((FILE *) fp);
  1142. }
  1143. static bool p_rename(const char *from, const char *to) {
  1144. return rename(from, to) == 0;
  1145. }
  1146. static bool p_remove(const char *path) {
  1147. return remove(path) == 0;
  1148. }
  1149. static bool p_mkdir(const char *path) {
  1150. return mkdir(path, 0775) == 0;
  1151. }
  1152. #else
  1153. static int p_stat(const char *path, size_t *size, time_t *mtime) {
  1154. (void) path, (void) size, (void) mtime;
  1155. return 0;
  1156. }
  1157. static void p_list(const char *path, void (*fn)(const char *, void *),
  1158. void *userdata) {
  1159. (void) path, (void) fn, (void) userdata;
  1160. }
  1161. static void *p_open(const char *path, int flags) {
  1162. (void) path, (void) flags;
  1163. return NULL;
  1164. }
  1165. static void p_close(void *fp) {
  1166. (void) fp;
  1167. }
  1168. static size_t p_read(void *fd, void *buf, size_t len) {
  1169. (void) fd, (void) buf, (void) len;
  1170. return 0;
  1171. }
  1172. static size_t p_write(void *fd, const void *buf, size_t len) {
  1173. (void) fd, (void) buf, (void) len;
  1174. return 0;
  1175. }
  1176. static size_t p_seek(void *fd, size_t offset) {
  1177. (void) fd, (void) offset;
  1178. return (size_t) ~0;
  1179. }
  1180. static bool p_rename(const char *from, const char *to) {
  1181. (void) from, (void) to;
  1182. return false;
  1183. }
  1184. static bool p_remove(const char *path) {
  1185. (void) path;
  1186. return false;
  1187. }
  1188. static bool p_mkdir(const char *path) {
  1189. (void) path;
  1190. return false;
  1191. }
  1192. #endif
  1193. struct mg_fs mg_fs_posix = {p_stat, p_list, p_open, p_close, p_read,
  1194. p_write, p_seek, p_rename, p_remove, p_mkdir};
  1195. #ifdef MG_ENABLE_LINES
  1196. #line 1 "src/http.c"
  1197. #endif
  1198. // Chunk deletion marker is the MSB in the "processed" counter
  1199. #define MG_DMARK ((size_t) 1 << (sizeof(size_t) * 8 - 1))
  1200. // Multipart POST example:
  1201. // --xyz
  1202. // Content-Disposition: form-data; name="val"
  1203. //
  1204. // abcdef
  1205. // --xyz
  1206. // Content-Disposition: form-data; name="foo"; filename="a.txt"
  1207. // Content-Type: text/plain
  1208. //
  1209. // hello world
  1210. //
  1211. // --xyz--
  1212. size_t mg_http_next_multipart(struct mg_str body, size_t ofs,
  1213. struct mg_http_part *part) {
  1214. struct mg_str cd = mg_str_n("Content-Disposition", 19);
  1215. const char *s = body.ptr;
  1216. size_t b = ofs, h1, h2, b1, b2, max = body.len;
  1217. // Init part params
  1218. if (part != NULL) part->name = part->filename = part->body = mg_str_n(0, 0);
  1219. // Skip boundary
  1220. while (b + 2 < max && s[b] != '\r' && s[b + 1] != '\n') b++;
  1221. if (b <= ofs || b + 2 >= max) return 0;
  1222. // MG_INFO(("B: %zu %zu [%.*s]", ofs, b - ofs, (int) (b - ofs), s));
  1223. // Skip headers
  1224. h1 = h2 = b + 2;
  1225. for (;;) {
  1226. while (h2 + 2 < max && s[h2] != '\r' && s[h2 + 1] != '\n') h2++;
  1227. if (h2 == h1) break;
  1228. if (h2 + 2 >= max) return 0;
  1229. // MG_INFO(("Header: [%.*s]", (int) (h2 - h1), &s[h1]));
  1230. if (part != NULL && h1 + cd.len + 2 < h2 && s[h1 + cd.len] == ':' &&
  1231. mg_ncasecmp(&s[h1], cd.ptr, cd.len) == 0) {
  1232. struct mg_str v = mg_str_n(&s[h1 + cd.len + 2], h2 - (h1 + cd.len + 2));
  1233. part->name = mg_http_get_header_var(v, mg_str_n("name", 4));
  1234. part->filename = mg_http_get_header_var(v, mg_str_n("filename", 8));
  1235. }
  1236. h1 = h2 = h2 + 2;
  1237. }
  1238. b1 = b2 = h2 + 2;
  1239. while (b2 + 2 + (b - ofs) + 2 < max && !(s[b2] == '\r' && s[b2 + 1] == '\n' &&
  1240. memcmp(&s[b2 + 2], s, b - ofs) == 0))
  1241. b2++;
  1242. if (b2 + 2 >= max) return 0;
  1243. if (part != NULL) part->body = mg_str_n(&s[b1], b2 - b1);
  1244. // MG_INFO(("Body: [%.*s]", (int) (b2 - b1), &s[b1]));
  1245. return b2 + 2;
  1246. }
  1247. void mg_http_bauth(struct mg_connection *c, const char *user,
  1248. const char *pass) {
  1249. struct mg_str u = mg_str(user), p = mg_str(pass);
  1250. size_t need = c->send.len + 36 + (u.len + p.len) * 2;
  1251. if (c->send.size < need) mg_iobuf_resize(&c->send, need);
  1252. if (c->send.size >= need) {
  1253. int i, n = 0;
  1254. char *buf = (char *) &c->send.buf[c->send.len + 21];
  1255. memcpy(&buf[-21], "Authorization: Basic ", 21); // DON'T use mg_send!
  1256. for (i = 0; i < (int) u.len; i++) {
  1257. n = mg_base64_update(((unsigned char *) u.ptr)[i], buf, n);
  1258. }
  1259. if (p.len > 0) {
  1260. n = mg_base64_update(':', buf, n);
  1261. for (i = 0; i < (int) p.len; i++) {
  1262. n = mg_base64_update(((unsigned char *) p.ptr)[i], buf, n);
  1263. }
  1264. }
  1265. n = mg_base64_final(buf, n);
  1266. c->send.len += 21 + (size_t) n + 2;
  1267. memcpy(&c->send.buf[c->send.len - 2], "\r\n", 2);
  1268. } else {
  1269. MG_ERROR(("%lu %s cannot resize iobuf %d->%d ", c->id, c->label,
  1270. (int) c->send.size, (int) need));
  1271. }
  1272. }
  1273. struct mg_str mg_http_var(struct mg_str buf, struct mg_str name) {
  1274. struct mg_str k, v, result = mg_str_n(NULL, 0);
  1275. while (mg_split(&buf, &k, &v, '&')) {
  1276. if (name.len == k.len && mg_ncasecmp(name.ptr, k.ptr, k.len) == 0) {
  1277. result = v;
  1278. break;
  1279. }
  1280. }
  1281. return result;
  1282. }
  1283. int mg_http_get_var(const struct mg_str *buf, const char *name, char *dst,
  1284. size_t dst_len) {
  1285. int len;
  1286. if (dst == NULL || dst_len == 0) {
  1287. len = -2; // Bad destination
  1288. } else if (buf->ptr == NULL || name == NULL || buf->len == 0) {
  1289. len = -1; // Bad source
  1290. dst[0] = '\0';
  1291. } else {
  1292. struct mg_str v = mg_http_var(*buf, mg_str(name));
  1293. if (v.ptr == NULL) {
  1294. len = -4; // Name does not exist
  1295. } else {
  1296. len = mg_url_decode(v.ptr, v.len, dst, dst_len, 1);
  1297. if (len < 0) len = -3; // Failed to decode
  1298. }
  1299. }
  1300. return len;
  1301. }
  1302. static bool isx(int c) {
  1303. return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
  1304. (c >= 'A' && c <= 'F');
  1305. }
  1306. int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len,
  1307. int is_form_url_encoded) {
  1308. size_t i, j;
  1309. for (i = j = 0; i < src_len && j + 1 < dst_len; i++, j++) {
  1310. if (src[i] == '%') {
  1311. // Use `i + 2 < src_len`, not `i < src_len - 2`, note small src_len
  1312. if (i + 2 < src_len && isx(src[i + 1]) && isx(src[i + 2])) {
  1313. mg_unhex(src + i + 1, 2, (uint8_t *) &dst[j]);
  1314. i += 2;
  1315. } else {
  1316. return -1;
  1317. }
  1318. } else if (is_form_url_encoded && src[i] == '+') {
  1319. dst[j] = ' ';
  1320. } else {
  1321. dst[j] = src[i];
  1322. }
  1323. }
  1324. if (j < dst_len) dst[j] = '\0'; // Null-terminate the destination
  1325. return i >= src_len && j < dst_len ? (int) j : -1;
  1326. }
  1327. static bool isok(uint8_t c) {
  1328. return c == '\n' || c == '\r' || c >= ' ';
  1329. }
  1330. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len) {
  1331. size_t i;
  1332. for (i = 0; i < buf_len; i++) {
  1333. if (!isok(buf[i])) return -1;
  1334. if ((i > 0 && buf[i] == '\n' && buf[i - 1] == '\n') ||
  1335. (i > 3 && buf[i] == '\n' && buf[i - 1] == '\r' && buf[i - 2] == '\n'))
  1336. return (int) i + 1;
  1337. }
  1338. return 0;
  1339. }
  1340. static const char *skip(const char *s, const char *e, const char *d,
  1341. struct mg_str *v) {
  1342. v->ptr = s;
  1343. while (s < e && *s != '\n' && strchr(d, *s) == NULL) s++;
  1344. v->len = (size_t) (s - v->ptr);
  1345. while (s < e && strchr(d, *s) != NULL) s++;
  1346. return s;
  1347. }
  1348. struct mg_str *mg_http_get_header(struct mg_http_message *h, const char *name) {
  1349. size_t i, n = strlen(name), max = sizeof(h->headers) / sizeof(h->headers[0]);
  1350. for (i = 0; i < max && h->headers[i].name.len > 0; i++) {
  1351. struct mg_str *k = &h->headers[i].name, *v = &h->headers[i].value;
  1352. if (n == k->len && mg_ncasecmp(k->ptr, name, n) == 0) return v;
  1353. }
  1354. return NULL;
  1355. }
  1356. static void mg_http_parse_headers(const char *s, const char *end,
  1357. struct mg_http_header *h, int max_headers) {
  1358. int i;
  1359. for (i = 0; i < max_headers; i++) {
  1360. struct mg_str k, v, tmp;
  1361. const char *he = skip(s, end, "\n", &tmp);
  1362. s = skip(s, he, ": \r\n", &k);
  1363. s = skip(s, he, "\r\n", &v);
  1364. if (k.len == tmp.len) continue;
  1365. while (v.len > 0 && v.ptr[v.len - 1] == ' ') v.len--; // Trim spaces
  1366. if (k.len == 0) break;
  1367. // MG_INFO(("--HH [%.*s] [%.*s] [%.*s]", (int) tmp.len - 1, tmp.ptr,
  1368. //(int) k.len, k.ptr, (int) v.len, v.ptr));
  1369. h[i].name = k;
  1370. h[i].value = v;
  1371. }
  1372. }
  1373. int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) {
  1374. int is_response, req_len = mg_http_get_request_len((unsigned char *) s, len);
  1375. const char *end = s + req_len, *qs;
  1376. struct mg_str *cl;
  1377. memset(hm, 0, sizeof(*hm));
  1378. if (req_len <= 0) return req_len;
  1379. hm->message.ptr = hm->head.ptr = s;
  1380. hm->body.ptr = end;
  1381. hm->head.len = (size_t) req_len;
  1382. hm->chunk.ptr = end;
  1383. hm->message.len = hm->body.len = (size_t) ~0; // Set body length to infinite
  1384. // Parse request line
  1385. s = skip(s, end, " ", &hm->method);
  1386. s = skip(s, end, " ", &hm->uri);
  1387. s = skip(s, end, "\r\n", &hm->proto);
  1388. // Sanity check. Allow protocol/reason to be empty
  1389. if (hm->method.len == 0 || hm->uri.len == 0) return -1;
  1390. // If URI contains '?' character, setup query string
  1391. if ((qs = (const char *) memchr(hm->uri.ptr, '?', hm->uri.len)) != NULL) {
  1392. hm->query.ptr = qs + 1;
  1393. hm->query.len = (size_t) (&hm->uri.ptr[hm->uri.len] - (qs + 1));
  1394. hm->uri.len = (size_t) (qs - hm->uri.ptr);
  1395. }
  1396. mg_http_parse_headers(s, end, hm->headers,
  1397. sizeof(hm->headers) / sizeof(hm->headers[0]));
  1398. if ((cl = mg_http_get_header(hm, "Content-Length")) != NULL) {
  1399. hm->body.len = (size_t) mg_to64(*cl);
  1400. hm->message.len = (size_t) req_len + hm->body.len;
  1401. }
  1402. // mg_http_parse() is used to parse both HTTP requests and HTTP
  1403. // responses. If HTTP response does not have Content-Length set, then
  1404. // body is read until socket is closed, i.e. body.len is infinite (~0).
  1405. //
  1406. // For HTTP requests though, according to
  1407. // http://tools.ietf.org/html/rfc7231#section-8.1.3,
  1408. // only POST and PUT methods have defined body semantics.
  1409. // Therefore, if Content-Length is not specified and methods are
  1410. // not one of PUT or POST, set body length to 0.
  1411. //
  1412. // So, if it is HTTP request, and Content-Length is not set,
  1413. // and method is not (PUT or POST) then reset body length to zero.
  1414. is_response = mg_ncasecmp(hm->method.ptr, "HTTP/", 5) == 0;
  1415. if (hm->body.len == (size_t) ~0 && !is_response &&
  1416. mg_vcasecmp(&hm->method, "PUT") != 0 &&
  1417. mg_vcasecmp(&hm->method, "POST") != 0) {
  1418. hm->body.len = 0;
  1419. hm->message.len = (size_t) req_len;
  1420. }
  1421. // The 204 (No content) responses also have 0 body length
  1422. if (hm->body.len == (size_t) ~0 && is_response &&
  1423. mg_vcasecmp(&hm->uri, "204") == 0) {
  1424. hm->body.len = 0;
  1425. hm->message.len = (size_t) req_len;
  1426. }
  1427. return req_len;
  1428. }
  1429. static void mg_http_vprintf_chunk(struct mg_connection *c, const char *fmt,
  1430. va_list ap) {
  1431. size_t len = c->send.len;
  1432. va_list tmp;
  1433. mg_send(c, " \r\n", 10);
  1434. va_copy(tmp, ap);
  1435. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
  1436. va_end(tmp);
  1437. if (c->send.len >= len + 10) {
  1438. mg_snprintf((char *) c->send.buf + len, 9, "%08lx", c->send.len - len - 10);
  1439. c->send.buf[len + 8] = '\r';
  1440. if (c->send.len == len + 10) c->is_resp = 0; // Last chunk, reset marker
  1441. }
  1442. mg_send(c, "\r\n", 2);
  1443. }
  1444. void mg_http_printf_chunk(struct mg_connection *c, const char *fmt, ...) {
  1445. va_list ap;
  1446. va_start(ap, fmt);
  1447. mg_http_vprintf_chunk(c, fmt, ap);
  1448. va_end(ap);
  1449. }
  1450. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len) {
  1451. mg_printf(c, "%lx\r\n", (unsigned long) len);
  1452. mg_send(c, buf, len);
  1453. mg_send(c, "\r\n", 2);
  1454. if (len == 0) c->is_resp = 0;
  1455. }
  1456. // clang-format off
  1457. static const char *mg_http_status_code_str(int status_code) {
  1458. switch (status_code) {
  1459. case 100: return "Continue";
  1460. case 201: return "Created";
  1461. case 202: return "Accepted";
  1462. case 204: return "No Content";
  1463. case 206: return "Partial Content";
  1464. case 301: return "Moved Permanently";
  1465. case 302: return "Found";
  1466. case 304: return "Not Modified";
  1467. case 400: return "Bad Request";
  1468. case 401: return "Unauthorized";
  1469. case 403: return "Forbidden";
  1470. case 404: return "Not Found";
  1471. case 418: return "I'm a teapot";
  1472. case 500: return "Internal Server Error";
  1473. case 501: return "Not Implemented";
  1474. default: return "OK";
  1475. }
  1476. }
  1477. // clang-format on
  1478. void mg_http_reply(struct mg_connection *c, int code, const char *headers,
  1479. const char *fmt, ...) {
  1480. va_list ap;
  1481. size_t len;
  1482. mg_printf(c, "HTTP/1.1 %d %s\r\n%sContent-Length: \r\n\r\n", code,
  1483. mg_http_status_code_str(code), headers == NULL ? "" : headers);
  1484. len = c->send.len;
  1485. va_start(ap, fmt);
  1486. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
  1487. va_end(ap);
  1488. if (c->send.len > 15) {
  1489. mg_snprintf((char *) &c->send.buf[len - 14], 11, "%010lu",
  1490. (unsigned long) (c->send.len - len));
  1491. c->is_resp = 0;
  1492. c->send.buf[len - 4] = '\r'; // Change ending 0 to space
  1493. }
  1494. c->is_resp = 0;
  1495. }
  1496. static void http_cb(struct mg_connection *, int, void *, void *);
  1497. static void restore_http_cb(struct mg_connection *c) {
  1498. mg_fs_close((struct mg_fd *) c->pfn_data);
  1499. c->pfn_data = NULL;
  1500. c->pfn = http_cb;
  1501. c->is_resp = 0;
  1502. }
  1503. char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime);
  1504. char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime) {
  1505. mg_snprintf(buf, len, "\"%lld.%lld\"", (int64_t) mtime, (int64_t) size);
  1506. return buf;
  1507. }
  1508. static void static_cb(struct mg_connection *c, int ev, void *ev_data,
  1509. void *fn_data) {
  1510. if (ev == MG_EV_WRITE || ev == MG_EV_POLL) {
  1511. struct mg_fd *fd = (struct mg_fd *) fn_data;
  1512. // Read to send IO buffer directly, avoid extra on-stack buffer
  1513. size_t n, max = MG_IO_SIZE, space, *cl = (size_t *) c->label;
  1514. if (c->send.size < max) mg_iobuf_resize(&c->send, max);
  1515. if (c->send.len >= c->send.size) return; // Rate limit
  1516. if ((space = c->send.size - c->send.len) > *cl) space = *cl;
  1517. n = fd->fs->rd(fd->fd, c->send.buf + c->send.len, space);
  1518. c->send.len += n;
  1519. *cl -= n;
  1520. if (n == 0) restore_http_cb(c);
  1521. } else if (ev == MG_EV_CLOSE) {
  1522. restore_http_cb(c);
  1523. }
  1524. (void) ev_data;
  1525. }
  1526. // Known mime types. Keep it outside guess_content_type() function, since
  1527. // some environments don't like it defined there.
  1528. // clang-format off
  1529. static struct mg_str s_known_types[] = {
  1530. MG_C_STR("html"), MG_C_STR("text/html; charset=utf-8"),
  1531. MG_C_STR("htm"), MG_C_STR("text/html; charset=utf-8"),
  1532. MG_C_STR("css"), MG_C_STR("text/css; charset=utf-8"),
  1533. MG_C_STR("js"), MG_C_STR("text/javascript; charset=utf-8"),
  1534. MG_C_STR("gif"), MG_C_STR("image/gif"),
  1535. MG_C_STR("png"), MG_C_STR("image/png"),
  1536. MG_C_STR("jpg"), MG_C_STR("image/jpeg"),
  1537. MG_C_STR("jpeg"), MG_C_STR("image/jpeg"),
  1538. MG_C_STR("woff"), MG_C_STR("font/woff"),
  1539. MG_C_STR("ttf"), MG_C_STR("font/ttf"),
  1540. MG_C_STR("svg"), MG_C_STR("image/svg+xml"),
  1541. MG_C_STR("txt"), MG_C_STR("text/plain; charset=utf-8"),
  1542. MG_C_STR("avi"), MG_C_STR("video/x-msvideo"),
  1543. MG_C_STR("csv"), MG_C_STR("text/csv"),
  1544. MG_C_STR("doc"), MG_C_STR("application/msword"),
  1545. MG_C_STR("exe"), MG_C_STR("application/octet-stream"),
  1546. MG_C_STR("gz"), MG_C_STR("application/gzip"),
  1547. MG_C_STR("ico"), MG_C_STR("image/x-icon"),
  1548. MG_C_STR("json"), MG_C_STR("application/json"),
  1549. MG_C_STR("mov"), MG_C_STR("video/quicktime"),
  1550. MG_C_STR("mp3"), MG_C_STR("audio/mpeg"),
  1551. MG_C_STR("mp4"), MG_C_STR("video/mp4"),
  1552. MG_C_STR("mpeg"), MG_C_STR("video/mpeg"),
  1553. MG_C_STR("pdf"), MG_C_STR("application/pdf"),
  1554. MG_C_STR("shtml"), MG_C_STR("text/html; charset=utf-8"),
  1555. MG_C_STR("tgz"), MG_C_STR("application/tar-gz"),
  1556. MG_C_STR("wav"), MG_C_STR("audio/wav"),
  1557. MG_C_STR("webp"), MG_C_STR("image/webp"),
  1558. MG_C_STR("zip"), MG_C_STR("application/zip"),
  1559. MG_C_STR("3gp"), MG_C_STR("video/3gpp"),
  1560. {0, 0},
  1561. };
  1562. // clang-format on
  1563. static struct mg_str guess_content_type(struct mg_str path, const char *extra) {
  1564. struct mg_str k, v, s = mg_str(extra);
  1565. size_t i = 0;
  1566. // Shrink path to its extension only
  1567. while (i < path.len && path.ptr[path.len - i - 1] != '.') i++;
  1568. path.ptr += path.len - i;
  1569. path.len = i;
  1570. // Process user-provided mime type overrides, if any
  1571. while (mg_commalist(&s, &k, &v)) {
  1572. if (mg_strcmp(path, k) == 0) return v;
  1573. }
  1574. // Process built-in mime types
  1575. for (i = 0; s_known_types[i].ptr != NULL; i += 2) {
  1576. if (mg_strcmp(path, s_known_types[i]) == 0) return s_known_types[i + 1];
  1577. }
  1578. return mg_str("text/plain; charset=utf-8");
  1579. }
  1580. static int getrange(struct mg_str *s, int64_t *a, int64_t *b) {
  1581. size_t i, numparsed = 0;
  1582. // MG_INFO(("%.*s", (int) s->len, s->ptr));
  1583. for (i = 0; i + 6 < s->len; i++) {
  1584. if (memcmp(&s->ptr[i], "bytes=", 6) == 0) {
  1585. struct mg_str p = mg_str_n(s->ptr + i + 6, s->len - i - 6);
  1586. if (p.len > 0 && p.ptr[0] >= '0' && p.ptr[0] <= '9') numparsed++;
  1587. *a = mg_to64(p);
  1588. // MG_INFO(("PPP [%.*s] %d", (int) p.len, p.ptr, numparsed));
  1589. while (p.len && p.ptr[0] >= '0' && p.ptr[0] <= '9') p.ptr++, p.len--;
  1590. if (p.len && p.ptr[0] == '-') p.ptr++, p.len--;
  1591. *b = mg_to64(p);
  1592. if (p.len > 0 && p.ptr[0] >= '0' && p.ptr[0] <= '9') numparsed++;
  1593. // MG_INFO(("PPP [%.*s] %d", (int) p.len, p.ptr, numparsed));
  1594. break;
  1595. }
  1596. }
  1597. return (int) numparsed;
  1598. }
  1599. void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
  1600. const char *path,
  1601. const struct mg_http_serve_opts *opts) {
  1602. char etag[64], tmp[MG_PATH_MAX];
  1603. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  1604. struct mg_fd *fd = path == NULL ? NULL : mg_fs_open(fs, path, MG_FS_READ);
  1605. size_t size = 0;
  1606. time_t mtime = 0;
  1607. struct mg_str *inm = NULL;
  1608. struct mg_str mime = guess_content_type(mg_str(path), opts->mime_types);
  1609. bool gzip = false;
  1610. // If file does not exist, we try to open file PATH.gz - and if such
  1611. // pre-compressed .gz file exists, serve it with the Content-Encoding: gzip
  1612. // Note - we ignore Accept-Encoding, cause we don't have a choice
  1613. if (fd == NULL) {
  1614. MG_DEBUG(("NULL [%s]", path));
  1615. mg_snprintf(tmp, sizeof(tmp), "%s.gz", path);
  1616. if ((fd = mg_fs_open(fs, tmp, MG_FS_READ)) != NULL) {
  1617. gzip = true;
  1618. path = tmp;
  1619. } else if (opts->page404 != NULL) {
  1620. // No precompressed file, serve 404
  1621. fd = mg_fs_open(fs, opts->page404, MG_FS_READ);
  1622. mime = guess_content_type(mg_str(path), opts->mime_types);
  1623. path = opts->page404;
  1624. }
  1625. }
  1626. if (fd == NULL || fs->st(path, &size, &mtime) == 0) {
  1627. mg_http_reply(c, 404, opts->extra_headers, "Not found\n");
  1628. mg_fs_close(fd);
  1629. // NOTE: mg_http_etag() call should go first!
  1630. } else if (mg_http_etag(etag, sizeof(etag), size, mtime) != NULL &&
  1631. (inm = mg_http_get_header(hm, "If-None-Match")) != NULL &&
  1632. mg_vcasecmp(inm, etag) == 0) {
  1633. mg_fs_close(fd);
  1634. mg_http_reply(c, 304, opts->extra_headers, "");
  1635. } else {
  1636. int n, status = 200;
  1637. char range[100];
  1638. int64_t r1 = 0, r2 = 0, cl = (int64_t) size;
  1639. // Handle Range header
  1640. struct mg_str *rh = mg_http_get_header(hm, "Range");
  1641. range[0] = '\0';
  1642. if (rh != NULL && (n = getrange(rh, &r1, &r2)) > 0 && r1 >= 0 && r2 >= 0) {
  1643. // If range is specified like "400-", set second limit to content len
  1644. if (n == 1) r2 = cl - 1;
  1645. if (r1 > r2 || r2 >= cl) {
  1646. status = 416;
  1647. cl = 0;
  1648. mg_snprintf(range, sizeof(range), "Content-Range: bytes */%lld\r\n",
  1649. (int64_t) size);
  1650. } else {
  1651. status = 206;
  1652. cl = r2 - r1 + 1;
  1653. mg_snprintf(range, sizeof(range),
  1654. "Content-Range: bytes %lld-%lld/%lld\r\n", r1, r1 + cl - 1,
  1655. (int64_t) size);
  1656. fs->sk(fd->fd, (size_t) r1);
  1657. }
  1658. }
  1659. mg_printf(c,
  1660. "HTTP/1.1 %d %s\r\n"
  1661. "Content-Type: %.*s\r\n"
  1662. "Etag: %s\r\n"
  1663. "Content-Length: %llu\r\n"
  1664. "%s%s%s\r\n",
  1665. status, mg_http_status_code_str(status), (int) mime.len, mime.ptr,
  1666. etag, cl, gzip ? "Content-Encoding: gzip\r\n" : "", range,
  1667. opts->extra_headers ? opts->extra_headers : "");
  1668. if (mg_vcasecmp(&hm->method, "HEAD") == 0) {
  1669. c->is_draining = 1;
  1670. c->is_resp = 0;
  1671. mg_fs_close(fd);
  1672. } else {
  1673. c->pfn = static_cb;
  1674. c->pfn_data = fd;
  1675. *(size_t *) c->label = (size_t) cl; // Track to-be-sent content length
  1676. }
  1677. }
  1678. }
  1679. struct printdirentrydata {
  1680. struct mg_connection *c;
  1681. struct mg_http_message *hm;
  1682. const struct mg_http_serve_opts *opts;
  1683. const char *dir;
  1684. };
  1685. static void printdirentry(const char *name, void *userdata) {
  1686. struct printdirentrydata *d = (struct printdirentrydata *) userdata;
  1687. struct mg_fs *fs = d->opts->fs == NULL ? &mg_fs_posix : d->opts->fs;
  1688. size_t size = 0;
  1689. time_t t = 0;
  1690. char path[MG_PATH_MAX], sz[40], mod[40];
  1691. int flags, n = 0;
  1692. // MG_DEBUG(("[%s] [%s]", d->dir, name));
  1693. if (mg_snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) >
  1694. sizeof(path)) {
  1695. MG_ERROR(("%s truncated", name));
  1696. } else if ((flags = fs->st(path, &size, &t)) == 0) {
  1697. MG_ERROR(("%lu stat(%s): %d", d->c->id, path, errno));
  1698. } else {
  1699. const char *slash = flags & MG_FS_DIR ? "/" : "";
  1700. if (flags & MG_FS_DIR) {
  1701. mg_snprintf(sz, sizeof(sz), "%s", "[DIR]");
  1702. } else {
  1703. mg_snprintf(sz, sizeof(sz), "%lld", (uint64_t) size);
  1704. }
  1705. mg_snprintf(mod, sizeof(mod), "%ld", (unsigned long) t);
  1706. n = (int) mg_url_encode(name, strlen(name), path, sizeof(path));
  1707. mg_printf(d->c,
  1708. " <tr><td><a href=\"%.*s%s\">%s%s</a></td>"
  1709. "<td name=%lu>%s</td><td name=%lld>%s</td></tr>\n",
  1710. n, path, slash, name, slash, (unsigned long) t, mod,
  1711. flags & MG_FS_DIR ? (int64_t) -1 : (int64_t) size, sz);
  1712. }
  1713. }
  1714. static void listdir(struct mg_connection *c, struct mg_http_message *hm,
  1715. const struct mg_http_serve_opts *opts, char *dir) {
  1716. const char *sort_js_code =
  1717. "<script>function srt(tb, sc, so, d) {"
  1718. "var tr = Array.prototype.slice.call(tb.rows, 0),"
  1719. "tr = tr.sort(function (a, b) { var c1 = a.cells[sc], c2 = b.cells[sc],"
  1720. "n1 = c1.getAttribute('name'), n2 = c2.getAttribute('name'), "
  1721. "t1 = a.cells[2].getAttribute('name'), "
  1722. "t2 = b.cells[2].getAttribute('name'); "
  1723. "return so * (t1 < 0 && t2 >= 0 ? -1 : t2 < 0 && t1 >= 0 ? 1 : "
  1724. "n1 ? parseInt(n2) - parseInt(n1) : "
  1725. "c1.textContent.trim().localeCompare(c2.textContent.trim())); });";
  1726. const char *sort_js_code2 =
  1727. "for (var i = 0; i < tr.length; i++) tb.appendChild(tr[i]); "
  1728. "if (!d) window.location.hash = ('sc=' + sc + '&so=' + so); "
  1729. "};"
  1730. "window.onload = function() {"
  1731. "var tb = document.getElementById('tb');"
  1732. "var m = /sc=([012]).so=(1|-1)/.exec(window.location.hash) || [0, 2, 1];"
  1733. "var sc = m[1], so = m[2]; document.onclick = function(ev) { "
  1734. "var c = ev.target.rel; if (c) {if (c == sc) so *= -1; srt(tb, c, so); "
  1735. "sc = c; ev.preventDefault();}};"
  1736. "srt(tb, sc, so, true);"
  1737. "}"
  1738. "</script>";
  1739. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  1740. struct printdirentrydata d = {c, hm, opts, dir};
  1741. char tmp[10], buf[MG_PATH_MAX];
  1742. size_t off, n;
  1743. int len = mg_url_decode(hm->uri.ptr, hm->uri.len, buf, sizeof(buf), 0);
  1744. struct mg_str uri = len > 0 ? mg_str_n(buf, (size_t) len) : hm->uri;
  1745. mg_printf(c,
  1746. "HTTP/1.1 200 OK\r\n"
  1747. "Content-Type: text/html; charset=utf-8\r\n"
  1748. "%s"
  1749. "Content-Length: \r\n\r\n",
  1750. opts->extra_headers == NULL ? "" : opts->extra_headers);
  1751. off = c->send.len; // Start of body
  1752. mg_printf(c,
  1753. "<!DOCTYPE html><html><head><title>Index of %.*s</title>%s%s"
  1754. "<style>th,td {text-align: left; padding-right: 1em; "
  1755. "font-family: monospace; }</style></head>"
  1756. "<body><h1>Index of %.*s</h1><table cellpadding=\"0\"><thead>"
  1757. "<tr><th><a href=\"#\" rel=\"0\">Name</a></th><th>"
  1758. "<a href=\"#\" rel=\"1\">Modified</a></th>"
  1759. "<th><a href=\"#\" rel=\"2\">Size</a></th></tr>"
  1760. "<tr><td colspan=\"3\"><hr></td></tr>"
  1761. "</thead>"
  1762. "<tbody id=\"tb\">\n",
  1763. (int) uri.len, uri.ptr, sort_js_code, sort_js_code2, (int) uri.len,
  1764. uri.ptr);
  1765. mg_printf(c, "%s",
  1766. " <tr><td><a href=\"..\">..</a></td>"
  1767. "<td name=-1></td><td name=-1>[DIR]</td></tr>\n");
  1768. fs->ls(dir, printdirentry, &d);
  1769. mg_printf(c,
  1770. "</tbody><tfoot><tr><td colspan=\"3\"><hr></td></tr></tfoot>"
  1771. "</table><address>Mongoose v.%s</address></body></html>\n",
  1772. MG_VERSION);
  1773. n = mg_snprintf(tmp, sizeof(tmp), "%lu", (unsigned long) (c->send.len - off));
  1774. if (n > sizeof(tmp)) n = 0;
  1775. memcpy(c->send.buf + off - 12, tmp, n); // Set content length
  1776. c->is_resp = 0; // Mark response end
  1777. }
  1778. // Resolve requested file into `path` and return its fs->st() result
  1779. static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm,
  1780. struct mg_fs *fs, struct mg_str url, struct mg_str dir,
  1781. char *path, size_t path_size) {
  1782. int flags, tmp;
  1783. // Append URI to the root_dir, and sanitize it
  1784. size_t n = mg_snprintf(path, path_size, "%.*s", (int) dir.len, dir.ptr);
  1785. if (n > path_size) n = path_size;
  1786. path[path_size - 1] = '\0';
  1787. if (n + 2 < path_size) path[n++] = '/', path[n] = '\0';
  1788. mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n,
  1789. path_size - n, 0);
  1790. path[path_size - 1] = '\0'; // Double-check
  1791. mg_remove_double_dots(path);
  1792. n = strlen(path);
  1793. while (n > 1 && path[n - 1] == '/') path[--n] = 0; // Trim trailing slashes
  1794. flags = mg_vcmp(&hm->uri, "/") == 0 ? MG_FS_DIR : fs->st(path, NULL, NULL);
  1795. MG_VERBOSE(("%lu %.*s -> %s %d", c->id, (int) hm->uri.len, hm->uri.ptr, path,
  1796. flags));
  1797. if (flags == 0) {
  1798. // Do nothing - let's caller decide
  1799. } else if ((flags & MG_FS_DIR) && hm->uri.len > 0 &&
  1800. hm->uri.ptr[hm->uri.len - 1] != '/') {
  1801. mg_printf(c,
  1802. "HTTP/1.1 301 Moved\r\n"
  1803. "Location: %.*s/\r\n"
  1804. "Content-Length: 0\r\n"
  1805. "\r\n",
  1806. (int) hm->uri.len, hm->uri.ptr);
  1807. flags = -1;
  1808. } else if (flags & MG_FS_DIR) {
  1809. if (((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX) > 0 &&
  1810. (tmp = fs->st(path, NULL, NULL)) != 0) ||
  1811. (mg_snprintf(path + n, path_size - n, "/index.shtml") > 0 &&
  1812. (tmp = fs->st(path, NULL, NULL)) != 0))) {
  1813. flags = tmp;
  1814. } else if ((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX ".gz") >
  1815. 0 &&
  1816. (tmp = fs->st(path, NULL, NULL)) !=
  1817. 0)) { // check for gzipped index
  1818. flags = tmp;
  1819. path[n + 1 + strlen(MG_HTTP_INDEX)] =
  1820. '\0'; // Remove appended .gz in index file name
  1821. } else {
  1822. path[n] = '\0'; // Remove appended index file name
  1823. }
  1824. }
  1825. return flags;
  1826. }
  1827. static int uri_to_path(struct mg_connection *c, struct mg_http_message *hm,
  1828. const struct mg_http_serve_opts *opts, char *path,
  1829. size_t path_size) {
  1830. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  1831. struct mg_str k, v, s = mg_str(opts->root_dir), u = {0, 0}, p = {0, 0};
  1832. while (mg_commalist(&s, &k, &v)) {
  1833. if (v.len == 0) v = k, k = mg_str("/");
  1834. if (hm->uri.len < k.len) continue;
  1835. if (mg_strcmp(k, mg_str_n(hm->uri.ptr, k.len)) != 0) continue;
  1836. u = k, p = v;
  1837. }
  1838. return uri_to_path2(c, hm, fs, u, p, path, path_size);
  1839. }
  1840. void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
  1841. const struct mg_http_serve_opts *opts) {
  1842. char path[MG_PATH_MAX];
  1843. const char *sp = opts->ssi_pattern;
  1844. int flags = uri_to_path(c, hm, opts, path, sizeof(path));
  1845. if (flags < 0) {
  1846. // Do nothing: the response has already been sent by uri_to_path()
  1847. } else if (flags & MG_FS_DIR) {
  1848. listdir(c, hm, opts, path);
  1849. } else if (flags && sp != NULL &&
  1850. mg_globmatch(sp, strlen(sp), path, strlen(path))) {
  1851. mg_http_serve_ssi(c, opts->root_dir, path);
  1852. } else {
  1853. mg_http_serve_file(c, hm, path, opts);
  1854. }
  1855. }
  1856. static bool mg_is_url_safe(int c) {
  1857. return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
  1858. (c >= 'A' && c <= 'Z') || c == '.' || c == '_' || c == '-' || c == '~';
  1859. }
  1860. size_t mg_url_encode(const char *s, size_t sl, char *buf, size_t len) {
  1861. size_t i, n = 0;
  1862. for (i = 0; i < sl; i++) {
  1863. int c = *(unsigned char *) &s[i];
  1864. if (n + 4 >= len) return 0;
  1865. if (mg_is_url_safe(c)) {
  1866. buf[n++] = s[i];
  1867. } else {
  1868. buf[n++] = '%';
  1869. mg_hex(&s[i], 1, &buf[n]);
  1870. n += 2;
  1871. }
  1872. }
  1873. return n;
  1874. }
  1875. void mg_http_creds(struct mg_http_message *hm, char *user, size_t userlen,
  1876. char *pass, size_t passlen) {
  1877. struct mg_str *v = mg_http_get_header(hm, "Authorization");
  1878. user[0] = pass[0] = '\0';
  1879. if (v != NULL && v->len > 6 && memcmp(v->ptr, "Basic ", 6) == 0) {
  1880. char buf[256];
  1881. int n = mg_base64_decode(v->ptr + 6, (int) v->len - 6, buf);
  1882. const char *p = (const char *) memchr(buf, ':', n > 0 ? (size_t) n : 0);
  1883. if (p != NULL) {
  1884. mg_snprintf(user, userlen, "%.*s", (int) (p - buf), buf);
  1885. mg_snprintf(pass, passlen, "%.*s", n - (int) (p - buf) - 1, p + 1);
  1886. }
  1887. } else if (v != NULL && v->len > 7 && memcmp(v->ptr, "Bearer ", 7) == 0) {
  1888. mg_snprintf(pass, passlen, "%.*s", (int) v->len - 7, v->ptr + 7);
  1889. } else if ((v = mg_http_get_header(hm, "Cookie")) != NULL) {
  1890. struct mg_str t = mg_http_get_header_var(*v, mg_str_n("access_token", 12));
  1891. if (t.len > 0) mg_snprintf(pass, passlen, "%.*s", (int) t.len, t.ptr);
  1892. } else {
  1893. mg_http_get_var(&hm->query, "access_token", pass, passlen);
  1894. }
  1895. }
  1896. static struct mg_str stripquotes(struct mg_str s) {
  1897. return s.len > 1 && s.ptr[0] == '"' && s.ptr[s.len - 1] == '"'
  1898. ? mg_str_n(s.ptr + 1, s.len - 2)
  1899. : s;
  1900. }
  1901. struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) {
  1902. size_t i;
  1903. for (i = 0; v.len > 0 && i + v.len + 2 < s.len; i++) {
  1904. if (s.ptr[i + v.len] == '=' && memcmp(&s.ptr[i], v.ptr, v.len) == 0) {
  1905. const char *p = &s.ptr[i + v.len + 1], *b = p, *x = &s.ptr[s.len];
  1906. int q = p < x && *p == '"' ? 1 : 0;
  1907. while (p < x &&
  1908. (q ? p == b || *p != '"' : *p != ';' && *p != ' ' && *p != ','))
  1909. p++;
  1910. // MG_INFO(("[%.*s] [%.*s] [%.*s]", (int) s.len, s.ptr, (int) v.len,
  1911. // v.ptr, (int) (p - b), b));
  1912. return stripquotes(mg_str_n(b, (size_t) (p - b + q)));
  1913. }
  1914. }
  1915. return mg_str_n(NULL, 0);
  1916. }
  1917. bool mg_http_match_uri(const struct mg_http_message *hm, const char *glob) {
  1918. return mg_match(hm->uri, mg_str(glob), NULL);
  1919. }
  1920. long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
  1921. struct mg_fs *fs, const char *path, size_t max_size) {
  1922. char buf[20] = "0";
  1923. long res = 0, offset;
  1924. mg_http_get_var(&hm->query, "offset", buf, sizeof(buf));
  1925. offset = strtol(buf, NULL, 0);
  1926. if (hm->body.len == 0) {
  1927. mg_http_reply(c, 200, "", "%ld", res); // Nothing to write
  1928. } else {
  1929. struct mg_fd *fd;
  1930. size_t current_size = 0;
  1931. MG_DEBUG(("%s -> %d bytes @ %ld", path, (int) hm->body.len, offset));
  1932. if (offset == 0) fs->rm(path); // If offset if 0, truncate file
  1933. fs->st(path, &current_size, NULL);
  1934. if (offset < 0) {
  1935. mg_http_reply(c, 400, "", "offset required");
  1936. res = -1;
  1937. } else if (offset > 0 && current_size != (size_t) offset) {
  1938. mg_http_reply(c, 400, "", "%s: offset mismatch", path);
  1939. res = -2;
  1940. } else if ((size_t) offset + hm->body.len > max_size) {
  1941. mg_http_reply(c, 400, "", "%s: over max size of %lu", path,
  1942. (unsigned long) max_size);
  1943. res = -3;
  1944. } else if ((fd = mg_fs_open(fs, path, MG_FS_WRITE)) == NULL) {
  1945. mg_http_reply(c, 400, "", "open(%s): %d", path, errno);
  1946. res = -4;
  1947. } else {
  1948. res = offset + (long) fs->wr(fd->fd, hm->body.ptr, hm->body.len);
  1949. mg_fs_close(fd);
  1950. mg_http_reply(c, 200, "", "%ld", res);
  1951. }
  1952. }
  1953. return res;
  1954. }
  1955. int mg_http_status(const struct mg_http_message *hm) {
  1956. return atoi(hm->uri.ptr);
  1957. }
  1958. // If a server sends data to the client using chunked encoding, Mongoose strips
  1959. // off the chunking prefix (hex length and \r\n) and suffix (\r\n), appends the
  1960. // stripped data to the body, and fires the MG_EV_HTTP_CHUNK event. When zero
  1961. // chunk is received, it fires MG_EV_HTTP_MSG, and the body is already have all
  1962. // chunking prefixes/suffixes stripped.
  1963. //
  1964. // If a server sends data without chunked encoding, we also fire MG_EV_CHUNK
  1965. // and MG_EV_HTTP_MSG in the end.
  1966. //
  1967. // We track the total processed body length in the c->pfn_data,
  1968. // by using void * pointer to store size_t value.
  1969. static bool getchunk(struct mg_str s, size_t *prefixlen, size_t *datalen) {
  1970. size_t i = 0, n;
  1971. while (i < s.len && s.ptr[i] != '\r' && s.ptr[i] != '\n') i++;
  1972. n = mg_unhexn(s.ptr, i);
  1973. // MG_INFO(("%d %d", (int) (i + n + 4), (int) s.len));
  1974. if (s.len < i + n + 4) return false; // Chunk not yet fully buffered
  1975. if (s.ptr[i] != '\r' || s.ptr[i + 1] != '\n') return false;
  1976. if (s.ptr[i + n + 2] != '\r' || s.ptr[i + n + 3] != '\n') return false;
  1977. *prefixlen = i + 2;
  1978. *datalen = n;
  1979. return true;
  1980. }
  1981. static bool mg_is_chunked(struct mg_http_message *hm) {
  1982. const char *needle = "chunked";
  1983. struct mg_str *te = mg_http_get_header(hm, "Transfer-Encoding");
  1984. return te != NULL && mg_vcasecmp(te, needle) == 0;
  1985. }
  1986. void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm) {
  1987. size_t ofs = (size_t) (hm->chunk.ptr - (char *) c->recv.buf);
  1988. mg_iobuf_del(&c->recv, ofs, hm->chunk.len);
  1989. c->pfn_data = (void *) ((size_t) c->pfn_data | MG_DMARK);
  1990. }
  1991. static void deliver_chunked_chunks(struct mg_connection *c, size_t hlen,
  1992. struct mg_http_message *hm, bool *next) {
  1993. // | ... headers ... | HEXNUM\r\n ..data.. \r\n | ......
  1994. // +------------------+--------------------------+----
  1995. // | hlen | chunk1 | ......
  1996. char *buf = (char *) &c->recv.buf[hlen], *p = buf;
  1997. size_t len = c->recv.len - hlen;
  1998. size_t processed = ((size_t) c->pfn_data) & ~MG_DMARK;
  1999. size_t mark, pl, dl, del = 0, ofs = 0;
  2000. bool last = false;
  2001. if (processed <= len) len -= processed, buf += processed;
  2002. while (!last && getchunk(mg_str_n(buf + ofs, len - ofs), &pl, &dl)) {
  2003. size_t saved = c->recv.len;
  2004. memmove(p + processed, buf + ofs + pl, dl);
  2005. // MG_INFO(("P2 [%.*s]", (int) (processed + dl), p));
  2006. hm->chunk = mg_str_n(p + processed, dl);
  2007. mg_call(c, MG_EV_HTTP_CHUNK, hm);
  2008. ofs += pl + dl + 2, del += pl + 2; // 2 is for \r\n suffix
  2009. processed += dl;
  2010. if (c->recv.len != saved) processed -= dl, buf -= dl;
  2011. mg_hexdump(c->recv.buf, hlen + processed);
  2012. last = (dl == 0);
  2013. }
  2014. mg_iobuf_del(&c->recv, hlen + processed, del);
  2015. mark = ((size_t) c->pfn_data) & MG_DMARK;
  2016. c->pfn_data = (void *) (processed | mark);
  2017. if (last) {
  2018. hm->body.len = processed;
  2019. hm->message.len = hlen + processed;
  2020. c->pfn_data = NULL;
  2021. if (mark) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
  2022. // MG_INFO(("LAST, mark: %lx", mark));
  2023. // mg_hexdump(c->recv.buf, c->recv.len);
  2024. }
  2025. }
  2026. static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
  2027. struct mg_http_message *hm, bool *next) {
  2028. size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK;
  2029. size_t deleted = ((size_t) c->pfn_data) & MG_DMARK;
  2030. hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen);
  2031. if (processed <= hm->chunk.len && !deleted) {
  2032. hm->chunk.len -= processed;
  2033. hm->chunk.ptr += processed;
  2034. }
  2035. left = hm->body.len < processed ? 0 : hm->body.len - processed;
  2036. if (hm->chunk.len > left) hm->chunk.len = left;
  2037. if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm);
  2038. processed += hm->chunk.len;
  2039. deleted = ((size_t) c->pfn_data) & MG_DMARK; // Re-evaluate after user call
  2040. if (processed >= hm->body.len) { // Last, 0-len chunk
  2041. hm->chunk.len = 0; // Reset length
  2042. mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler
  2043. c->pfn_data = NULL; // Reset processed counter
  2044. if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
  2045. } else {
  2046. c->pfn_data = (void *) (processed | deleted); // if it is set
  2047. }
  2048. }
  2049. static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
  2050. if (ev == MG_EV_READ || ev == MG_EV_CLOSE) {
  2051. struct mg_http_message hm;
  2052. // mg_hexdump(c->recv.buf, c->recv.len);
  2053. while (c->recv.buf != NULL && c->recv.len > 0) {
  2054. bool next = false;
  2055. int hlen = mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
  2056. if (hlen < 0) {
  2057. mg_error(c, "HTTP parse:\n%.*s", (int) c->recv.len, c->recv.buf);
  2058. break;
  2059. }
  2060. if (c->is_resp) break; // Response is still generated
  2061. if (hlen == 0) break; // Request is not buffered yet
  2062. if (ev == MG_EV_CLOSE) { // If client did not set Content-Length
  2063. hm.message.len = c->recv.len; // and closes now, deliver a MSG
  2064. hm.body.len = hm.message.len - (size_t) (hm.body.ptr - hm.message.ptr);
  2065. }
  2066. if (mg_is_chunked(&hm)) {
  2067. deliver_chunked_chunks(c, (size_t) hlen, &hm, &next);
  2068. } else {
  2069. deliver_normal_chunks(c, (size_t) hlen, &hm, &next);
  2070. }
  2071. if (next) continue; // Chunks & request were deleted
  2072. // Chunk events are delivered. If we have full body, deliver MSG
  2073. if (c->recv.len < hm.message.len) break;
  2074. if (c->is_accepted) c->is_resp = 1; // Start generating response
  2075. mg_call(c, MG_EV_HTTP_MSG, &hm); // User handler can clear is_resp
  2076. mg_iobuf_del(&c->recv, 0, hm.message.len);
  2077. }
  2078. }
  2079. (void) evd, (void) fnd;
  2080. }
  2081. struct mg_connection *mg_http_connect(struct mg_mgr *mgr, const char *url,
  2082. mg_event_handler_t fn, void *fn_data) {
  2083. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  2084. if (c != NULL) c->pfn = http_cb;
  2085. return c;
  2086. }
  2087. struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url,
  2088. mg_event_handler_t fn, void *fn_data) {
  2089. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  2090. if (c != NULL) c->pfn = http_cb;
  2091. return c;
  2092. }
  2093. #ifdef MG_ENABLE_LINES
  2094. #line 1 "src/iobuf.c"
  2095. #endif
  2096. // Not using memset for zeroing memory, cause it can be dropped by compiler
  2097. // See https://github.com/cesanta/mongoose/pull/1265
  2098. static void zeromem(volatile unsigned char *buf, size_t len) {
  2099. if (buf != NULL) {
  2100. while (len--) *buf++ = 0;
  2101. }
  2102. }
  2103. static size_t roundup(size_t size, size_t align) {
  2104. return align == 0 ? size : (size + align - 1) / align * align;
  2105. }
  2106. int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
  2107. int ok = 1;
  2108. new_size = roundup(new_size, io->align);
  2109. if (new_size == 0) {
  2110. zeromem(io->buf, io->size);
  2111. free(io->buf);
  2112. io->buf = NULL;
  2113. io->len = io->size = 0;
  2114. } else if (new_size != io->size) {
  2115. // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the
  2116. // porting to some obscure platforms like FreeRTOS
  2117. void *p = calloc(1, new_size);
  2118. if (p != NULL) {
  2119. size_t len = new_size < io->len ? new_size : io->len;
  2120. if (len > 0) memmove(p, io->buf, len);
  2121. zeromem(io->buf, io->size);
  2122. free(io->buf);
  2123. io->buf = (unsigned char *) p;
  2124. io->size = new_size;
  2125. } else {
  2126. ok = 0;
  2127. MG_ERROR(("%lld->%lld", (uint64_t) io->size, (uint64_t) new_size));
  2128. }
  2129. }
  2130. return ok;
  2131. }
  2132. int mg_iobuf_init(struct mg_iobuf *io, size_t size, size_t align) {
  2133. io->buf = NULL;
  2134. io->align = align;
  2135. io->size = io->len = 0;
  2136. return mg_iobuf_resize(io, size);
  2137. }
  2138. size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf,
  2139. size_t len) {
  2140. size_t new_size = roundup(io->len + len, io->align);
  2141. mg_iobuf_resize(io, new_size); // Attempt to resize
  2142. if (new_size != io->size) len = 0; // Resize failure, append nothing
  2143. if (ofs < io->len) memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs);
  2144. if (buf != NULL) memmove(io->buf + ofs, buf, len);
  2145. if (ofs > io->len) io->len += ofs - io->len;
  2146. io->len += len;
  2147. return len;
  2148. }
  2149. size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
  2150. if (ofs > io->len) ofs = io->len;
  2151. if (ofs + len > io->len) len = io->len - ofs;
  2152. if (io->buf) memmove(io->buf + ofs, io->buf + ofs + len, io->len - ofs - len);
  2153. if (io->buf) zeromem(io->buf + io->len - len, len);
  2154. io->len -= len;
  2155. return len;
  2156. }
  2157. void mg_iobuf_free(struct mg_iobuf *io) {
  2158. mg_iobuf_resize(io, 0);
  2159. }
  2160. #ifdef MG_ENABLE_LINES
  2161. #line 1 "src/json.c"
  2162. #endif
  2163. static const char *escapeseq(int esc) {
  2164. return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
  2165. }
  2166. static char json_esc(int c, int esc) {
  2167. const char *p, *esc1 = escapeseq(esc), *esc2 = escapeseq(!esc);
  2168. for (p = esc1; *p != '\0'; p++) {
  2169. if (*p == c) return esc2[p - esc1];
  2170. }
  2171. return 0;
  2172. }
  2173. static int mg_pass_string(const char *s, int len) {
  2174. int i;
  2175. for (i = 0; i < len; i++) {
  2176. if (s[i] == '\\' && i + 1 < len && json_esc(s[i + 1], 1)) {
  2177. i++;
  2178. } else if (s[i] == '\0') {
  2179. return MG_JSON_INVALID;
  2180. } else if (s[i] == '"') {
  2181. return i;
  2182. }
  2183. }
  2184. return MG_JSON_INVALID;
  2185. }
  2186. static double mg_atod(const char *p, int len, int *numlen) {
  2187. double d = 0.0;
  2188. int i = 0, sign = 1;
  2189. // Sign
  2190. if (i < len && *p == '-') {
  2191. sign = -1, i++;
  2192. } else if (i < len && *p == '+') {
  2193. i++;
  2194. }
  2195. // Decimal
  2196. for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
  2197. d *= 10.0;
  2198. d += p[i] - '0';
  2199. }
  2200. d *= sign;
  2201. // Fractional
  2202. if (i < len && p[i] == '.') {
  2203. double frac = 0.0, base = 0.1;
  2204. i++;
  2205. for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
  2206. frac += base * (p[i] - '0');
  2207. base /= 10.0;
  2208. }
  2209. d += frac * sign;
  2210. }
  2211. // Exponential
  2212. if (i < len && (p[i] == 'e' || p[i] == 'E')) {
  2213. int j, exp = 0, minus = 0;
  2214. i++;
  2215. if (i < len && p[i] == '-') minus = 1, i++;
  2216. if (i < len && p[i] == '+') i++;
  2217. while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
  2218. exp = exp * 10 + (p[i++] - '0');
  2219. if (minus) exp = -exp;
  2220. for (j = 0; j < exp; j++) d *= 10.0;
  2221. for (j = 0; j < -exp; j++) d /= 10.0;
  2222. }
  2223. if (numlen != NULL) *numlen = i;
  2224. return d;
  2225. }
  2226. int mg_json_get(struct mg_str json, const char *path, int *toklen) {
  2227. const char *s = json.ptr;
  2228. int len = (int) json.len;
  2229. enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE;
  2230. unsigned char nesting[MG_JSON_MAX_DEPTH];
  2231. int i = 0; // Current offset in `s`
  2232. int j = 0; // Offset in `s` we're looking for (return value)
  2233. int depth = 0; // Current depth (nesting level)
  2234. int ed = 0; // Expected depth
  2235. int pos = 1; // Current position in `path`
  2236. int ci = -1, ei = -1; // Current and expected index in array
  2237. if (path[0] != '$') return MG_JSON_INVALID;
  2238. #define MG_CHECKRET(x) \
  2239. do { \
  2240. if (depth == ed && path[pos] == '\0' && ci == ei) { \
  2241. if (toklen) *toklen = i - j + 1; \
  2242. return j; \
  2243. } \
  2244. } while (0)
  2245. // In the ascii table, the distance between `[` and `]` is 2.
  2246. // Ditto for `{` and `}`. Hence +2 in the code below.
  2247. #define MG_EOO(x) \
  2248. do { \
  2249. if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND; \
  2250. if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
  2251. depth--; \
  2252. MG_CHECKRET(x); \
  2253. } while (0)
  2254. for (i = 0; i < len; i++) {
  2255. unsigned char c = ((unsigned char *) s)[i];
  2256. if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
  2257. switch (expecting) {
  2258. case S_VALUE:
  2259. // p("V %s [%.*s] %d %d %d %d\n", path, pos, path, depth, ed, ci, ei);
  2260. if (depth == ed) j = i;
  2261. if (c == '{') {
  2262. if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
  2263. if (depth == ed && path[pos] == '.' && ci == ei) {
  2264. // If we start the object, reset array indices
  2265. ed++, pos++, ci = ei = -1;
  2266. }
  2267. nesting[depth++] = c;
  2268. expecting = S_KEY;
  2269. break;
  2270. } else if (c == '[') {
  2271. if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
  2272. if (depth == ed && path[pos] == '[' && ei == ci) {
  2273. ed++, pos++, ci = 0;
  2274. for (ei = 0; path[pos] != ']' && path[pos] != '\0'; pos++) {
  2275. ei *= 10;
  2276. ei += path[pos] - '0';
  2277. }
  2278. if (path[pos] != 0) pos++;
  2279. }
  2280. nesting[depth++] = c;
  2281. break;
  2282. } else if (c == ']' && depth > 0) { // Empty array
  2283. MG_EOO(']');
  2284. } else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
  2285. i += 3;
  2286. } else if (c == 'n' && i + 3 < len && memcmp(&s[i], "null", 4) == 0) {
  2287. i += 3;
  2288. } else if (c == 'f' && i + 4 < len && memcmp(&s[i], "false", 5) == 0) {
  2289. i += 4;
  2290. } else if (c == '-' || ((c >= '0' && c <= '9'))) {
  2291. int numlen = 0;
  2292. mg_atod(&s[i], len - i, &numlen);
  2293. i += numlen - 1;
  2294. } else if (c == '"') {
  2295. int n = mg_pass_string(&s[i + 1], len - i - 1);
  2296. if (n < 0) return n;
  2297. i += n + 1;
  2298. } else {
  2299. return MG_JSON_INVALID;
  2300. }
  2301. MG_CHECKRET('V');
  2302. if (depth == ed && ei >= 0) ci++;
  2303. expecting = S_COMMA_OR_EOO;
  2304. break;
  2305. case S_KEY:
  2306. if (c == '"') {
  2307. int n = mg_pass_string(&s[i + 1], len - i - 1);
  2308. if (n < 0) return n;
  2309. if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
  2310. if (depth < ed) return MG_JSON_NOT_FOUND;
  2311. // printf("K %s [%.*s] [%.*s] %d %d %d\n", path, pos, path, n,
  2312. // &s[i + 1], n, depth, ed);
  2313. // NOTE(cpq): in the check sequence below is important.
  2314. // strncmp() must go first: it fails fast if the remaining length of
  2315. // the path is smaller than `n`.
  2316. if (depth == ed && path[pos - 1] == '.' &&
  2317. strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
  2318. (path[pos + n] == '\0' || path[pos + n] == '.' ||
  2319. path[pos + n] == '[')) {
  2320. pos += n;
  2321. }
  2322. i += n + 1;
  2323. expecting = S_COLON;
  2324. } else if (c == '}') { // Empty object
  2325. MG_EOO('}');
  2326. expecting = S_COMMA_OR_EOO;
  2327. } else {
  2328. return MG_JSON_INVALID;
  2329. }
  2330. break;
  2331. case S_COLON:
  2332. if (c == ':') {
  2333. expecting = S_VALUE;
  2334. } else {
  2335. return MG_JSON_INVALID;
  2336. }
  2337. break;
  2338. case S_COMMA_OR_EOO:
  2339. if (depth <= 0) {
  2340. return MG_JSON_INVALID;
  2341. } else if (c == ',') {
  2342. expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE;
  2343. } else if (c == ']' || c == '}') {
  2344. MG_EOO('O');
  2345. if (depth == ed && ei >= 0) ci++;
  2346. } else {
  2347. return MG_JSON_INVALID;
  2348. }
  2349. break;
  2350. }
  2351. }
  2352. return MG_JSON_NOT_FOUND;
  2353. }
  2354. bool mg_json_get_num(struct mg_str json, const char *path, double *v) {
  2355. int n, toklen, found = 0;
  2356. if ((n = mg_json_get(json, path, &toklen)) >= 0 &&
  2357. (json.ptr[n] == '-' || (json.ptr[n] >= '0' && json.ptr[n] <= '9'))) {
  2358. if (v != NULL) *v = mg_atod(json.ptr + n, toklen, NULL);
  2359. found = 1;
  2360. }
  2361. return found;
  2362. }
  2363. bool mg_json_get_bool(struct mg_str json, const char *path, bool *v) {
  2364. int found = 0, off = mg_json_get(json, path, NULL);
  2365. if (off >= 0 && (json.ptr[off] == 't' || json.ptr[off] == 'f')) {
  2366. if (v != NULL) *v = json.ptr[off] == 't';
  2367. found = 1;
  2368. }
  2369. return found;
  2370. }
  2371. static bool json_unescape(const char *s, size_t len, char *to, size_t n) {
  2372. size_t i, j;
  2373. for (i = 0, j = 0; i < len && j < n; i++, j++) {
  2374. if (s[i] == '\\' && i + 5 < len && s[i + 1] == 'u') {
  2375. // \uXXXX escape. We could process a simple one-byte chars
  2376. // \u00xx from the ASCII range. More complex chars would require
  2377. // dragging in a UTF8 library, which is too much for us
  2378. if (s[i + 2] != '0' || s[i + 3] != '0') return false; // Give up
  2379. ((unsigned char *) to)[j] = (unsigned char) mg_unhexn(s + i + 4, 2);
  2380. i += 5;
  2381. } else if (s[i] == '\\' && i + 1 < len) {
  2382. char c = json_esc(s[i + 1], 0);
  2383. if (c == 0) return false;
  2384. to[j] = c;
  2385. i++;
  2386. } else {
  2387. to[j] = s[i];
  2388. }
  2389. }
  2390. if (j >= n) return false;
  2391. if (n > 0) to[j] = '\0';
  2392. return true;
  2393. }
  2394. char *mg_json_get_str(struct mg_str json, const char *path) {
  2395. char *result = NULL;
  2396. int len = 0, off = mg_json_get(json, path, &len);
  2397. if (off >= 0 && len > 1 && json.ptr[off] == '"') {
  2398. if ((result = (char *) calloc(1, (size_t) len)) != NULL &&
  2399. !json_unescape(json.ptr + off + 1, (size_t) (len - 2), result,
  2400. (size_t) len)) {
  2401. free(result);
  2402. result = NULL;
  2403. }
  2404. }
  2405. return result;
  2406. }
  2407. char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) {
  2408. char *result = NULL;
  2409. int len = 0, off = mg_json_get(json, path, &len);
  2410. if (off >= 0 && json.ptr[off] == '"' && len > 1 &&
  2411. (result = (char *) calloc(1, (size_t) len)) != NULL) {
  2412. int k = mg_base64_decode(json.ptr + off + 1, len - 2, result);
  2413. if (slen != NULL) *slen = k;
  2414. }
  2415. return result;
  2416. }
  2417. char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) {
  2418. char *result = NULL;
  2419. int len = 0, off = mg_json_get(json, path, &len);
  2420. if (off >= 0 && json.ptr[off] == '"' && len > 1 &&
  2421. (result = (char *) calloc(1, (size_t) len / 2)) != NULL) {
  2422. mg_unhex(json.ptr + off + 1, (size_t) (len - 2), (uint8_t *) result);
  2423. result[len / 2 - 1] = '\0';
  2424. if (slen != NULL) *slen = len / 2 - 1;
  2425. }
  2426. return result;
  2427. }
  2428. long mg_json_get_long(struct mg_str json, const char *path, long dflt) {
  2429. double dv;
  2430. long result = dflt;
  2431. if (mg_json_get_num(json, path, &dv)) result = (long) dv;
  2432. return result;
  2433. }
  2434. #ifdef MG_ENABLE_LINES
  2435. #line 1 "src/log.c"
  2436. #endif
  2437. static void default_logger(char c, void *param) {
  2438. putchar(c);
  2439. (void) c, (void) param;
  2440. }
  2441. static int s_level = MG_LL_INFO;
  2442. static mg_pfn_t s_log_func = default_logger;
  2443. static void *s_log_func_param = NULL;
  2444. void mg_log_set_fn(mg_pfn_t fn, void *param) {
  2445. s_log_func = fn;
  2446. s_log_func_param = param;
  2447. }
  2448. static void logc(unsigned char c) {
  2449. s_log_func((char) c, s_log_func_param);
  2450. }
  2451. static void logs(const char *buf, size_t len) {
  2452. size_t i;
  2453. for (i = 0; i < len; i++) logc(((unsigned char *) buf)[i]);
  2454. }
  2455. void mg_log_set(int log_level) {
  2456. MG_DEBUG(("Setting log level to %d", log_level));
  2457. s_level = log_level;
  2458. }
  2459. bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
  2460. if (level <= s_level) {
  2461. const char *p = strrchr(file, '/');
  2462. char buf[41];
  2463. size_t n;
  2464. if (p == NULL) p = strrchr(file, '\\');
  2465. n = mg_snprintf(buf, sizeof(buf), "%llx %d %s:%d:%s", mg_millis(), level,
  2466. p == NULL ? file : p + 1, line, fname);
  2467. if (n > sizeof(buf) - 2) n = sizeof(buf) - 2;
  2468. while (n < sizeof(buf)) buf[n++] = ' ';
  2469. logs(buf, n - 1);
  2470. return true;
  2471. } else {
  2472. return false;
  2473. }
  2474. }
  2475. void mg_log(const char *fmt, ...) {
  2476. va_list ap;
  2477. va_start(ap, fmt);
  2478. mg_vxprintf(s_log_func, s_log_func_param, fmt, &ap);
  2479. va_end(ap);
  2480. logc((unsigned char) '\n');
  2481. }
  2482. static unsigned char nibble(unsigned c) {
  2483. return (unsigned char) (c < 10 ? c + '0' : c + 'W');
  2484. }
  2485. #define ISPRINT(x) ((x) >= ' ' && (x) <= '~')
  2486. void mg_hexdump(const void *buf, size_t len) {
  2487. const unsigned char *p = (const unsigned char *) buf;
  2488. unsigned char ascii[16], alen = 0;
  2489. size_t i;
  2490. for (i = 0; i < len; i++) {
  2491. if ((i % 16) == 0) {
  2492. // Print buffered ascii chars
  2493. if (i > 0) logs(" ", 2), logs((char *) ascii, 16), logc('\n'), alen = 0;
  2494. // Print hex address, then \t
  2495. logc(nibble((i >> 12) & 15)), logc(nibble((i >> 8) & 15)),
  2496. logc(nibble((i >> 4) & 15)), logc('0'), logs(" ", 3);
  2497. }
  2498. logc(nibble(p[i] >> 4)), logc(nibble(p[i] & 15)); // Two nibbles, e.g. c5
  2499. logc(' '); // Space after hex number
  2500. ascii[alen++] = ISPRINT(p[i]) ? p[i] : '.'; // Add to the ascii buf
  2501. }
  2502. while (alen < 16) logs(" ", 3), ascii[alen++] = ' ';
  2503. logs(" ", 2), logs((char *) ascii, 16), logc('\n');
  2504. }
  2505. #ifdef MG_ENABLE_LINES
  2506. #line 1 "src/md5.c"
  2507. #endif
  2508. #if defined(MG_ENABLE_MD5) && MG_ENABLE_MD5
  2509. #if !defined(BYTE_ORDER) && defined(__BYTE_ORDER)
  2510. #define BYTE_ORDER __BYTE_ORDER
  2511. #ifndef LITTLE_ENDIAN
  2512. #define LITTLE_ENDIAN __LITTLE_ENDIAN
  2513. #endif /* LITTLE_ENDIAN */
  2514. #ifndef BIG_ENDIAN
  2515. #define BIG_ENDIAN __LITTLE_ENDIAN
  2516. #endif /* BIG_ENDIAN */
  2517. #endif /* BYTE_ORDER */
  2518. static void mg_byte_reverse(unsigned char *buf, unsigned longs) {
  2519. /* Forrest: MD5 expect LITTLE_ENDIAN, swap if BIG_ENDIAN */
  2520. #if BYTE_ORDER == BIG_ENDIAN
  2521. do {
  2522. uint32_t t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
  2523. ((unsigned) buf[1] << 8 | buf[0]);
  2524. *(uint32_t *) buf = t;
  2525. buf += 4;
  2526. } while (--longs);
  2527. #else
  2528. (void) buf;
  2529. (void) longs;
  2530. #endif
  2531. }
  2532. #define F1(x, y, z) (z ^ (x & (y ^ z)))
  2533. #define F2(x, y, z) F1(z, x, y)
  2534. #define F3(x, y, z) (x ^ y ^ z)
  2535. #define F4(x, y, z) (y ^ (x | ~z))
  2536. #define MD5STEP(f, w, x, y, z, data, s) \
  2537. (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
  2538. /*
  2539. * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
  2540. * initialization constants.
  2541. */
  2542. void mg_md5_init(mg_md5_ctx *ctx) {
  2543. ctx->buf[0] = 0x67452301;
  2544. ctx->buf[1] = 0xefcdab89;
  2545. ctx->buf[2] = 0x98badcfe;
  2546. ctx->buf[3] = 0x10325476;
  2547. ctx->bits[0] = 0;
  2548. ctx->bits[1] = 0;
  2549. }
  2550. static void mg_md5_transform(uint32_t buf[4], uint32_t const in[16]) {
  2551. uint32_t a, b, c, d;
  2552. a = buf[0];
  2553. b = buf[1];
  2554. c = buf[2];
  2555. d = buf[3];
  2556. MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  2557. MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  2558. MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  2559. MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  2560. MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  2561. MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  2562. MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  2563. MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  2564. MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  2565. MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  2566. MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  2567. MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  2568. MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  2569. MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  2570. MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  2571. MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  2572. MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  2573. MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  2574. MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  2575. MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  2576. MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  2577. MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  2578. MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  2579. MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  2580. MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  2581. MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  2582. MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  2583. MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  2584. MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  2585. MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  2586. MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  2587. MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  2588. MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  2589. MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  2590. MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  2591. MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  2592. MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  2593. MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  2594. MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  2595. MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  2596. MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  2597. MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  2598. MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  2599. MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  2600. MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  2601. MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  2602. MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  2603. MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  2604. MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  2605. MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  2606. MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  2607. MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  2608. MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  2609. MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  2610. MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  2611. MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  2612. MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  2613. MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  2614. MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  2615. MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  2616. MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  2617. MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  2618. MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  2619. MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  2620. buf[0] += a;
  2621. buf[1] += b;
  2622. buf[2] += c;
  2623. buf[3] += d;
  2624. }
  2625. void mg_md5_update(mg_md5_ctx *ctx, const unsigned char *buf, size_t len) {
  2626. uint32_t t;
  2627. t = ctx->bits[0];
  2628. if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++;
  2629. ctx->bits[1] += (uint32_t) len >> 29;
  2630. t = (t >> 3) & 0x3f;
  2631. if (t) {
  2632. unsigned char *p = (unsigned char *) ctx->in + t;
  2633. t = 64 - t;
  2634. if (len < t) {
  2635. memcpy(p, buf, len);
  2636. return;
  2637. }
  2638. memcpy(p, buf, t);
  2639. mg_byte_reverse(ctx->in, 16);
  2640. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  2641. buf += t;
  2642. len -= t;
  2643. }
  2644. while (len >= 64) {
  2645. memcpy(ctx->in, buf, 64);
  2646. mg_byte_reverse(ctx->in, 16);
  2647. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  2648. buf += 64;
  2649. len -= 64;
  2650. }
  2651. memcpy(ctx->in, buf, len);
  2652. }
  2653. void mg_md5_final(mg_md5_ctx *ctx, unsigned char digest[16]) {
  2654. unsigned count;
  2655. unsigned char *p;
  2656. uint32_t *a;
  2657. count = (ctx->bits[0] >> 3) & 0x3F;
  2658. p = ctx->in + count;
  2659. *p++ = 0x80;
  2660. count = 64 - 1 - count;
  2661. if (count < 8) {
  2662. memset(p, 0, count);
  2663. mg_byte_reverse(ctx->in, 16);
  2664. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  2665. memset(ctx->in, 0, 56);
  2666. } else {
  2667. memset(p, 0, count - 8);
  2668. }
  2669. mg_byte_reverse(ctx->in, 14);
  2670. a = (uint32_t *) ctx->in;
  2671. a[14] = ctx->bits[0];
  2672. a[15] = ctx->bits[1];
  2673. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  2674. mg_byte_reverse((unsigned char *) ctx->buf, 4);
  2675. memcpy(digest, ctx->buf, 16);
  2676. memset((char *) ctx, 0, sizeof(*ctx));
  2677. }
  2678. #endif
  2679. #ifdef MG_ENABLE_LINES
  2680. #line 1 "src/mqtt.c"
  2681. #endif
  2682. #define MQTT_CLEAN_SESSION 0x02
  2683. #define MQTT_HAS_WILL 0x04
  2684. #define MQTT_WILL_RETAIN 0x20
  2685. #define MQTT_HAS_PASSWORD 0x40
  2686. #define MQTT_HAS_USER_NAME 0x80
  2687. void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
  2688. uint32_t len) {
  2689. uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
  2690. buf[0] = (uint8_t) ((cmd << 4) | flags);
  2691. do {
  2692. *vlen = len % 0x80;
  2693. len /= 0x80;
  2694. if (len > 0) *vlen |= 0x80;
  2695. vlen++;
  2696. } while (len > 0 && vlen < &buf[sizeof(buf)]);
  2697. mg_send(c, buf, (size_t) (vlen - buf));
  2698. }
  2699. static void mg_send_u16(struct mg_connection *c, uint16_t value) {
  2700. mg_send(c, &value, sizeof(value));
  2701. }
  2702. void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
  2703. char rnd[10], client_id[21], zero = 0;
  2704. struct mg_str cid = opts->client_id;
  2705. uint32_t total_len = 7 + 1 + 2 + 2;
  2706. uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0};
  2707. if (cid.len == 0) {
  2708. mg_random(rnd, sizeof(rnd));
  2709. mg_hex(rnd, sizeof(rnd), client_id);
  2710. client_id[sizeof(client_id) - 1] = '\0';
  2711. cid = mg_str(client_id);
  2712. }
  2713. if (hdr[6] == 0) hdr[6] = 4; // If version is not set, use 4 (3.1.1)
  2714. c->is_mqtt5 = hdr[6] == 5; // Set version 5 flag
  2715. hdr[7] = (uint8_t) ((opts->will_qos & 3) << 3); // Connection flags
  2716. if (opts->user.len > 0) {
  2717. total_len += 2 + (uint32_t) opts->user.len;
  2718. hdr[7] |= MQTT_HAS_USER_NAME;
  2719. }
  2720. if (opts->pass.len > 0) {
  2721. total_len += 2 + (uint32_t) opts->pass.len;
  2722. hdr[7] |= MQTT_HAS_PASSWORD;
  2723. }
  2724. if (opts->will_topic.len > 0 && opts->will_message.len > 0) {
  2725. total_len +=
  2726. 4 + (uint32_t) opts->will_topic.len + (uint32_t) opts->will_message.len;
  2727. hdr[7] |= MQTT_HAS_WILL;
  2728. }
  2729. if (opts->clean || cid.len == 0) hdr[7] |= MQTT_CLEAN_SESSION;
  2730. if (opts->will_retain) hdr[7] |= MQTT_WILL_RETAIN;
  2731. total_len += (uint32_t) cid.len;
  2732. if (c->is_mqtt5) total_len += 1U + (hdr[7] & MQTT_HAS_WILL ? 1U : 0);
  2733. mg_mqtt_send_header(c, MQTT_CMD_CONNECT, 0, total_len);
  2734. mg_send(c, hdr, sizeof(hdr));
  2735. // keepalive == 0 means "do not disconnect us!"
  2736. mg_send_u16(c, mg_htons((uint16_t) opts->keepalive));
  2737. if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); // V5 properties
  2738. mg_send_u16(c, mg_htons((uint16_t) cid.len));
  2739. mg_send(c, cid.ptr, cid.len);
  2740. if (hdr[7] & MQTT_HAS_WILL) {
  2741. if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); // will props
  2742. mg_send_u16(c, mg_htons((uint16_t) opts->will_topic.len));
  2743. mg_send(c, opts->will_topic.ptr, opts->will_topic.len);
  2744. mg_send_u16(c, mg_htons((uint16_t) opts->will_message.len));
  2745. mg_send(c, opts->will_message.ptr, opts->will_message.len);
  2746. }
  2747. if (opts->user.len > 0) {
  2748. mg_send_u16(c, mg_htons((uint16_t) opts->user.len));
  2749. mg_send(c, opts->user.ptr, opts->user.len);
  2750. }
  2751. if (opts->pass.len > 0) {
  2752. mg_send_u16(c, mg_htons((uint16_t) opts->pass.len));
  2753. mg_send(c, opts->pass.ptr, opts->pass.len);
  2754. }
  2755. }
  2756. void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic,
  2757. struct mg_str data, int qos, bool retain) {
  2758. uint8_t flags = (uint8_t) (((qos & 3) << 1) | (retain ? 1 : 0)), zero = 0;
  2759. uint32_t len = 2 + (uint32_t) topic.len + (uint32_t) data.len;
  2760. MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) topic.len, (char *) topic.ptr,
  2761. (int) data.len, (char *) data.ptr));
  2762. if (qos > 0) len += 2;
  2763. if (c->is_mqtt5) len++;
  2764. mg_mqtt_send_header(c, MQTT_CMD_PUBLISH, flags, len);
  2765. mg_send_u16(c, mg_htons((uint16_t) topic.len));
  2766. mg_send(c, topic.ptr, topic.len);
  2767. if (qos > 0) {
  2768. if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
  2769. mg_send_u16(c, mg_htons(c->mgr->mqtt_id));
  2770. }
  2771. if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero));
  2772. mg_send(c, data.ptr, data.len);
  2773. }
  2774. void mg_mqtt_sub(struct mg_connection *c, struct mg_str topic, int qos) {
  2775. uint8_t qos_ = qos & 3, zero = 0;
  2776. uint32_t len = 2 + (uint32_t) topic.len + 2 + 1 + (c->is_mqtt5 ? 1 : 0);
  2777. mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, 2, len);
  2778. if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
  2779. mg_send_u16(c, mg_htons(c->mgr->mqtt_id));
  2780. if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero));
  2781. mg_send_u16(c, mg_htons((uint16_t) topic.len));
  2782. mg_send(c, topic.ptr, topic.len);
  2783. mg_send(c, &qos_, sizeof(qos_));
  2784. }
  2785. int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version,
  2786. struct mg_mqtt_message *m) {
  2787. uint8_t lc = 0, *p, *end;
  2788. uint32_t n = 0, len_len = 0;
  2789. memset(m, 0, sizeof(*m));
  2790. m->dgram.ptr = (char *) buf;
  2791. if (len < 2) return MQTT_INCOMPLETE;
  2792. m->cmd = (uint8_t) (buf[0] >> 4);
  2793. m->qos = (buf[0] >> 1) & 3;
  2794. n = len_len = 0;
  2795. p = (uint8_t *) buf + 1;
  2796. while ((size_t) (p - buf) < len) {
  2797. lc = *((uint8_t *) p++);
  2798. n += (uint32_t) ((lc & 0x7f) << 7 * len_len);
  2799. len_len++;
  2800. if (!(lc & 0x80)) break;
  2801. if (len_len >= 4) return MQTT_MALFORMED;
  2802. }
  2803. end = p + n;
  2804. if ((lc & 0x80) || (end > buf + len)) return MQTT_INCOMPLETE;
  2805. m->dgram.len = (size_t) (end - buf);
  2806. switch (m->cmd) {
  2807. case MQTT_CMD_CONNACK:
  2808. if (end - p < 2) return MQTT_MALFORMED;
  2809. m->ack = p[1];
  2810. break;
  2811. case MQTT_CMD_PUBACK:
  2812. case MQTT_CMD_PUBREC:
  2813. case MQTT_CMD_PUBREL:
  2814. case MQTT_CMD_PUBCOMP:
  2815. case MQTT_CMD_SUBSCRIBE:
  2816. case MQTT_CMD_SUBACK:
  2817. case MQTT_CMD_UNSUBSCRIBE:
  2818. case MQTT_CMD_UNSUBACK:
  2819. if (p + 2 > end) return MQTT_MALFORMED;
  2820. m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  2821. p += 2;
  2822. break;
  2823. case MQTT_CMD_PUBLISH: {
  2824. if (p + 2 > end) return MQTT_MALFORMED;
  2825. m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  2826. m->topic.ptr = (char *) p + 2;
  2827. p += 2 + m->topic.len;
  2828. if (p > end) return MQTT_MALFORMED;
  2829. if (m->qos > 0) {
  2830. if (p + 2 > end) return MQTT_MALFORMED;
  2831. m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  2832. p += 2;
  2833. }
  2834. if (p >= end) return MQTT_MALFORMED;
  2835. if (version == 5) p += 1 + p[0]; // Skip options
  2836. if (p > end) return MQTT_MALFORMED;
  2837. m->data.ptr = (char *) p;
  2838. m->data.len = (size_t) (end - p);
  2839. break;
  2840. }
  2841. default:
  2842. break;
  2843. }
  2844. return MQTT_OK;
  2845. }
  2846. static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
  2847. void *fn_data) {
  2848. if (ev == MG_EV_READ) {
  2849. for (;;) {
  2850. uint8_t version = c->is_mqtt5 ? 5 : 4;
  2851. struct mg_mqtt_message mm;
  2852. int rc = mg_mqtt_parse(c->recv.buf, c->recv.len, version, &mm);
  2853. if (rc == MQTT_MALFORMED) {
  2854. MG_ERROR(("%lu MQTT malformed message", c->id));
  2855. c->is_closing = 1;
  2856. break;
  2857. } else if (rc == MQTT_OK) {
  2858. MG_VERBOSE(("%p MQTT CMD %d len %d [%.*s]", c->fd, mm.cmd,
  2859. (int) mm.dgram.len, (int) mm.data.len, mm.data.ptr));
  2860. switch (mm.cmd) {
  2861. case MQTT_CMD_CONNACK:
  2862. mg_call(c, MG_EV_MQTT_OPEN, &mm.ack);
  2863. if (mm.ack == 0) {
  2864. MG_DEBUG(("%lu Connected", c->id));
  2865. } else {
  2866. MG_ERROR(("%lu MQTT auth failed, code %d", c->id, mm.ack));
  2867. c->is_closing = 1;
  2868. }
  2869. break;
  2870. case MQTT_CMD_PUBLISH: {
  2871. MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) mm.topic.len,
  2872. mm.topic.ptr, (int) mm.data.len, mm.data.ptr));
  2873. if (mm.qos > 0) {
  2874. uint16_t id = mg_htons(mm.id);
  2875. mg_mqtt_send_header(c, MQTT_CMD_PUBACK, 0, sizeof(id));
  2876. mg_send(c, &id, sizeof(id));
  2877. }
  2878. mg_call(c, MG_EV_MQTT_MSG, &mm);
  2879. break;
  2880. }
  2881. }
  2882. mg_call(c, MG_EV_MQTT_CMD, &mm);
  2883. mg_iobuf_del(&c->recv, 0, mm.dgram.len);
  2884. } else {
  2885. break;
  2886. }
  2887. }
  2888. }
  2889. (void) ev_data;
  2890. (void) fn_data;
  2891. }
  2892. void mg_mqtt_ping(struct mg_connection *nc) {
  2893. mg_mqtt_send_header(nc, MQTT_CMD_PINGREQ, 0, 0);
  2894. }
  2895. void mg_mqtt_pong(struct mg_connection *nc) {
  2896. mg_mqtt_send_header(nc, MQTT_CMD_PINGRESP, 0, 0);
  2897. }
  2898. void mg_mqtt_disconnect(struct mg_connection *nc) {
  2899. mg_mqtt_send_header(nc, MQTT_CMD_DISCONNECT, 0, 0);
  2900. }
  2901. struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url,
  2902. const struct mg_mqtt_opts *opts,
  2903. mg_event_handler_t fn, void *fn_data) {
  2904. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  2905. if (c != NULL) {
  2906. struct mg_mqtt_opts empty;
  2907. memset(&empty, 0, sizeof(empty));
  2908. mg_mqtt_login(c, opts == NULL ? &empty : opts);
  2909. c->pfn = mqtt_cb;
  2910. }
  2911. return c;
  2912. }
  2913. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  2914. mg_event_handler_t fn, void *fn_data) {
  2915. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  2916. if (c != NULL) c->pfn = mqtt_cb, c->pfn_data = mgr;
  2917. return c;
  2918. }
  2919. #ifdef MG_ENABLE_LINES
  2920. #line 1 "src/net.c"
  2921. #endif
  2922. size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) {
  2923. size_t old = c->send.len;
  2924. va_list tmp;
  2925. va_copy(tmp, ap);
  2926. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
  2927. return c->send.len - old;
  2928. }
  2929. size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
  2930. size_t len = 0;
  2931. va_list ap;
  2932. va_start(ap, fmt);
  2933. len = mg_vprintf(c, fmt, ap);
  2934. va_end(ap);
  2935. return len;
  2936. }
  2937. char *mg_straddr(struct mg_addr *a, char *buf, size_t len) {
  2938. char tmp[30];
  2939. const char *fmt = a->is_ip6 ? "[%s]:%d" : "%s:%d";
  2940. mg_ntoa(a, tmp, sizeof(tmp));
  2941. mg_snprintf(buf, len, fmt, tmp, (int) mg_ntohs(a->port));
  2942. return buf;
  2943. }
  2944. char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len) {
  2945. if (addr->is_ip6) {
  2946. uint16_t *p = (uint16_t *) addr->ip6;
  2947. mg_snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x", mg_htons(p[0]),
  2948. mg_htons(p[1]), mg_htons(p[2]), mg_htons(p[3]), mg_htons(p[4]),
  2949. mg_htons(p[5]), mg_htons(p[6]), mg_htons(p[7]));
  2950. } else {
  2951. uint8_t p[4];
  2952. memcpy(p, &addr->ip, sizeof(p));
  2953. mg_snprintf(buf, len, "%d.%d.%d.%d", (int) p[0], (int) p[1], (int) p[2],
  2954. (int) p[3]);
  2955. }
  2956. return buf;
  2957. }
  2958. static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
  2959. if (mg_vcasecmp(&str, "localhost") != 0) return false;
  2960. addr->ip = mg_htonl(0x7f000001);
  2961. addr->is_ip6 = false;
  2962. return true;
  2963. }
  2964. static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
  2965. if (str.len > 0) return false;
  2966. addr->ip = 0;
  2967. addr->is_ip6 = false;
  2968. return true;
  2969. }
  2970. static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
  2971. uint8_t data[4] = {0, 0, 0, 0};
  2972. size_t i, num_dots = 0;
  2973. for (i = 0; i < str.len; i++) {
  2974. if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
  2975. int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
  2976. if (octet > 255) return false;
  2977. data[num_dots] = (uint8_t) octet;
  2978. } else if (str.ptr[i] == '.') {
  2979. if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
  2980. num_dots++;
  2981. } else {
  2982. return false;
  2983. }
  2984. }
  2985. if (num_dots != 3 || str.ptr[i - 1] == '.') return false;
  2986. memcpy(&addr->ip, data, sizeof(data));
  2987. addr->is_ip6 = false;
  2988. return true;
  2989. }
  2990. static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
  2991. int i;
  2992. if (str.len < 14) return false;
  2993. if (str.ptr[0] != ':' || str.ptr[1] != ':' || str.ptr[6] != ':') return false;
  2994. for (i = 2; i < 6; i++) {
  2995. if (str.ptr[i] != 'f' && str.ptr[i] != 'F') return false;
  2996. }
  2997. if (!mg_aton4(mg_str_n(&str.ptr[7], str.len - 7), addr)) return false;
  2998. memset(addr->ip6, 0, sizeof(addr->ip6));
  2999. addr->ip6[10] = addr->ip6[11] = 255;
  3000. memcpy(&addr->ip6[12], &addr->ip, 4);
  3001. addr->is_ip6 = true;
  3002. return true;
  3003. }
  3004. static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
  3005. size_t i, j = 0, n = 0, dc = 42;
  3006. if (str.len > 2 && str.ptr[0] == '[') str.ptr++, str.len -= 2;
  3007. if (mg_v4mapped(str, addr)) return true;
  3008. for (i = 0; i < str.len; i++) {
  3009. if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') ||
  3010. (str.ptr[i] >= 'a' && str.ptr[i] <= 'f') ||
  3011. (str.ptr[i] >= 'A' && str.ptr[i] <= 'F')) {
  3012. unsigned long val;
  3013. if (i > j + 3) return false;
  3014. // MG_DEBUG(("%zu %zu [%.*s]", i, j, (int) (i - j + 1), &str.ptr[j]));
  3015. val = mg_unhexn(&str.ptr[j], i - j + 1);
  3016. addr->ip6[n] = (uint8_t) ((val >> 8) & 255);
  3017. addr->ip6[n + 1] = (uint8_t) (val & 255);
  3018. } else if (str.ptr[i] == ':') {
  3019. j = i + 1;
  3020. if (i > 0 && str.ptr[i - 1] == ':') {
  3021. dc = n; // Double colon
  3022. if (i > 1 && str.ptr[i - 2] == ':') return false;
  3023. } else if (i > 0) {
  3024. n += 2;
  3025. }
  3026. if (n > 14) return false;
  3027. addr->ip6[n] = addr->ip6[n + 1] = 0; // For trailing ::
  3028. } else {
  3029. return false;
  3030. }
  3031. }
  3032. if (n < 14 && dc == 42) return false;
  3033. if (n < 14) {
  3034. memmove(&addr->ip6[dc + (14 - n)], &addr->ip6[dc], n - dc + 2);
  3035. memset(&addr->ip6[dc], 0, 14 - n);
  3036. }
  3037. addr->is_ip6 = true;
  3038. return true;
  3039. }
  3040. bool mg_aton(struct mg_str str, struct mg_addr *addr) {
  3041. // MG_INFO(("[%.*s]", (int) str.len, str.ptr));
  3042. return mg_atone(str, addr) || mg_atonl(str, addr) || mg_aton4(str, addr) ||
  3043. mg_aton6(str, addr);
  3044. }
  3045. struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) {
  3046. struct mg_connection *c =
  3047. (struct mg_connection *) calloc(1, sizeof(*c) + mgr->extraconnsize);
  3048. if (c != NULL) {
  3049. c->mgr = mgr;
  3050. c->send.align = c->recv.align = MG_IO_SIZE;
  3051. c->id = ++mgr->nextid;
  3052. }
  3053. return c;
  3054. }
  3055. void mg_close_conn(struct mg_connection *c) {
  3056. mg_resolve_cancel(c); // Close any pending DNS query
  3057. LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
  3058. if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
  3059. if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
  3060. // Order of operations is important. `MG_EV_CLOSE` event must be fired
  3061. // before we deallocate received data, see #1331
  3062. mg_call(c, MG_EV_CLOSE, NULL);
  3063. MG_DEBUG(("%lu %p closed", c->id, c->fd));
  3064. mg_tls_free(c);
  3065. mg_iobuf_free(&c->recv);
  3066. mg_iobuf_free(&c->send);
  3067. memset(c, 0, sizeof(*c));
  3068. free(c);
  3069. }
  3070. struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
  3071. mg_event_handler_t fn, void *fn_data) {
  3072. struct mg_connection *c = NULL;
  3073. if (url == NULL || url[0] == '\0') {
  3074. MG_ERROR(("null url"));
  3075. } else if ((c = mg_alloc_conn(mgr)) == NULL) {
  3076. MG_ERROR(("OOM"));
  3077. } else {
  3078. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  3079. c->is_udp = (strncmp(url, "udp:", 4) == 0);
  3080. c->fn = fn;
  3081. c->is_client = true;
  3082. c->fd = (void *) (size_t) -1; // Set to invalid socket
  3083. c->fn_data = fn_data;
  3084. MG_DEBUG(("%lu -1 %s", c->id, url));
  3085. mg_call(c, MG_EV_OPEN, NULL);
  3086. mg_resolve(c, url);
  3087. }
  3088. return c;
  3089. }
  3090. struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
  3091. mg_event_handler_t fn, void *fn_data) {
  3092. struct mg_connection *c = NULL;
  3093. if ((c = mg_alloc_conn(mgr)) == NULL) {
  3094. MG_ERROR(("OOM %s", url));
  3095. } else if (!mg_open_listener(c, url)) {
  3096. MG_ERROR(("Failed: %s, errno %d", url, errno));
  3097. free(c);
  3098. c = NULL;
  3099. } else {
  3100. c->is_listening = 1;
  3101. c->is_udp = strncmp(url, "udp:", 4) == 0;
  3102. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  3103. c->fn = fn;
  3104. c->fn_data = fn_data;
  3105. mg_call(c, MG_EV_OPEN, NULL);
  3106. MG_DEBUG(("%lu %p %s", c->id, c->fd, url));
  3107. }
  3108. return c;
  3109. }
  3110. struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
  3111. mg_event_handler_t fn, void *fn_data) {
  3112. struct mg_connection *c = mg_alloc_conn(mgr);
  3113. if (c != NULL) {
  3114. c->fd = (void *) (size_t) fd;
  3115. c->fn = fn;
  3116. c->fn_data = fn_data;
  3117. MG_EPOLL_ADD(c);
  3118. mg_call(c, MG_EV_OPEN, NULL);
  3119. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  3120. }
  3121. return c;
  3122. }
  3123. struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
  3124. unsigned flags, void (*fn)(void *), void *arg) {
  3125. struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
  3126. mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
  3127. t->id = mgr->timerid++;
  3128. return t;
  3129. }
  3130. void mg_mgr_free(struct mg_mgr *mgr) {
  3131. struct mg_connection *c;
  3132. struct mg_timer *tmp, *t = mgr->timers;
  3133. while (t != NULL) tmp = t->next, free(t), t = tmp;
  3134. mgr->timers = NULL; // Important. Next call to poll won't touch timers
  3135. for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
  3136. mg_mgr_poll(mgr, 0);
  3137. #if MG_ARCH == MG_ARCH_FREERTOS_TCP
  3138. FreeRTOS_DeleteSocketSet(mgr->ss);
  3139. #endif
  3140. MG_DEBUG(("All connections closed"));
  3141. #if MG_ENABLE_EPOLL
  3142. if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
  3143. #endif
  3144. }
  3145. void mg_mgr_init(struct mg_mgr *mgr) {
  3146. memset(mgr, 0, sizeof(*mgr));
  3147. #if MG_ENABLE_EPOLL
  3148. if ((mgr->epoll_fd = epoll_create1(0)) < 0) MG_ERROR(("epoll: %d", errno));
  3149. #else
  3150. mgr->epoll_fd = -1;
  3151. #endif
  3152. #if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  3153. // clang-format off
  3154. { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
  3155. // clang-format on
  3156. #elif MG_ARCH == MG_ARCH_FREERTOS_TCP
  3157. mgr->ss = FreeRTOS_CreateSocketSet();
  3158. #elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
  3159. // Ignore SIGPIPE signal, so if client cancels the request, it
  3160. // won't kill the whole process.
  3161. signal(SIGPIPE, SIG_IGN);
  3162. #endif
  3163. mgr->dnstimeout = 3000;
  3164. mgr->dns4.url = "udp://8.8.8.8:53";
  3165. mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
  3166. }
  3167. #ifdef MG_ENABLE_LINES
  3168. #line 1 "src/rpc.c"
  3169. #endif
  3170. void mg_rpc_add(struct mg_rpc **head, struct mg_str method,
  3171. void (*fn)(struct mg_rpc_req *), void *fn_data) {
  3172. struct mg_rpc *rpc = (struct mg_rpc *) calloc(1, sizeof(*rpc));
  3173. rpc->method = mg_strdup(method), rpc->fn = fn, rpc->fn_data = fn_data;
  3174. rpc->next = *head, *head = rpc;
  3175. }
  3176. void mg_rpc_del(struct mg_rpc **head, void (*fn)(struct mg_rpc_req *)) {
  3177. struct mg_rpc *r;
  3178. while ((r = *head) != NULL) {
  3179. if (r->fn == fn || fn == NULL) {
  3180. *head = r->next;
  3181. free((void *) r->method.ptr);
  3182. free(r);
  3183. } else {
  3184. head = &(*head)->next;
  3185. }
  3186. }
  3187. }
  3188. static void mg_rpc_call(struct mg_rpc_req *r, struct mg_str method) {
  3189. struct mg_rpc *h = r->head == NULL ? NULL : *r->head;
  3190. while (h != NULL && !mg_match(method, h->method, NULL)) h = h->next;
  3191. if (h != NULL) {
  3192. r->rpc = h;
  3193. h->fn(r);
  3194. } else {
  3195. mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) method.len, method.ptr);
  3196. }
  3197. }
  3198. void mg_rpc_process(struct mg_rpc_req *r) {
  3199. int len, off = mg_json_get(r->frame, "$.method", &len);
  3200. if (off > 0 && r->frame.ptr[off] == '"') {
  3201. struct mg_str method = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2);
  3202. mg_rpc_call(r, method);
  3203. } else if ((off = mg_json_get(r->frame, "$.result", &len)) > 0 ||
  3204. (off = mg_json_get(r->frame, "$.error", &len)) > 0) {
  3205. mg_rpc_call(r, mg_str("")); // JSON response! call "" method handler
  3206. } else {
  3207. mg_rpc_err(r, -32700, "%.*Q", (int) r->frame.len, r->frame.ptr); // Invalid
  3208. }
  3209. }
  3210. void mg_rpc_vok(struct mg_rpc_req *r, const char *fmt, va_list *ap) {
  3211. int len, off = mg_json_get(r->frame, "$.id", &len);
  3212. if (off > 0) {
  3213. mg_xprintf(r->pfn, r->pfn_data, "{%Q:%.*s,%Q:", "id", len,
  3214. &r->frame.ptr[off], "result");
  3215. mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
  3216. mg_xprintf(r->pfn, r->pfn_data, "}");
  3217. }
  3218. }
  3219. void mg_rpc_ok(struct mg_rpc_req *r, const char *fmt, ...) {
  3220. va_list ap;
  3221. va_start(ap, fmt);
  3222. mg_rpc_vok(r, fmt, &ap);
  3223. va_end(ap);
  3224. }
  3225. void mg_rpc_verr(struct mg_rpc_req *r, int code, const char *fmt, va_list *ap) {
  3226. int len, off = mg_json_get(r->frame, "$.id", &len);
  3227. mg_xprintf(r->pfn, r->pfn_data, "{");
  3228. if (off > 0) {
  3229. mg_xprintf(r->pfn, r->pfn_data, "%Q:%.*s,", "id", len, &r->frame.ptr[off]);
  3230. }
  3231. mg_xprintf(r->pfn, r->pfn_data, "%Q:{%Q:%d,%Q:", "error", "code", code,
  3232. "message");
  3233. mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
  3234. mg_xprintf(r->pfn, r->pfn_data, "}}");
  3235. }
  3236. void mg_rpc_err(struct mg_rpc_req *r, int code, const char *fmt, ...) {
  3237. va_list ap;
  3238. va_start(ap, fmt);
  3239. mg_rpc_verr(r, code, fmt, &ap);
  3240. va_end(ap);
  3241. }
  3242. static size_t print_methods(mg_pfn_t pfn, void *pfn_data, va_list *ap) {
  3243. struct mg_rpc *h, **head = (struct mg_rpc **) va_arg(*ap, void **);
  3244. size_t len = 0;
  3245. for (h = *head; h != NULL; h = h->next) {
  3246. len += mg_xprintf(pfn, pfn_data, "%s%.*Q", h == *head ? "" : ",",
  3247. (int) h->method.len, h->method.ptr);
  3248. }
  3249. return len;
  3250. }
  3251. void mg_rpc_list(struct mg_rpc_req *r) {
  3252. mg_rpc_ok(r, "[%M]", print_methods, r->head);
  3253. }
  3254. #ifdef MG_ENABLE_LINES
  3255. #line 1 "src/sha1.c"
  3256. #endif
  3257. /* Copyright(c) By Steve Reid <steve@edmweb.com> */
  3258. /* 100% Public Domain */
  3259. /*
  3260. * clang with std=-c99 uses __LITTLE_ENDIAN, by default
  3261. * while for ex, RTOS gcc - LITTLE_ENDIAN, by default
  3262. * it depends on __USE_BSD, but let's have everything
  3263. */
  3264. #if !defined(BYTE_ORDER) && defined(__BYTE_ORDER)
  3265. #define BYTE_ORDER __BYTE_ORDER
  3266. #ifndef LITTLE_ENDIAN
  3267. #define LITTLE_ENDIAN __LITTLE_ENDIAN
  3268. #endif /* LITTLE_ENDIAN */
  3269. #ifndef BIG_ENDIAN
  3270. #define BIG_ENDIAN __LITTLE_ENDIAN
  3271. #endif /* BIG_ENDIAN */
  3272. #endif /* BYTE_ORDER */
  3273. union char64long16 {
  3274. unsigned char c[64];
  3275. uint32_t l[16];
  3276. };
  3277. #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  3278. static uint32_t blk0(union char64long16 *block, int i) {
  3279. /* Forrest: SHA expect BIG_ENDIAN, swap if LITTLE_ENDIAN */
  3280. #if BYTE_ORDER == LITTLE_ENDIAN
  3281. block->l[i] =
  3282. (rol(block->l[i], 24) & 0xFF00FF00) | (rol(block->l[i], 8) & 0x00FF00FF);
  3283. #endif
  3284. return block->l[i];
  3285. }
  3286. /* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */
  3287. #undef blk
  3288. #undef R0
  3289. #undef R1
  3290. #undef R2
  3291. #undef R3
  3292. #undef R4
  3293. #define blk(i) \
  3294. (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \
  3295. block->l[(i + 2) & 15] ^ block->l[i & 15], \
  3296. 1))
  3297. #define R0(v, w, x, y, z, i) \
  3298. z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \
  3299. w = rol(w, 30);
  3300. #define R1(v, w, x, y, z, i) \
  3301. z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
  3302. w = rol(w, 30);
  3303. #define R2(v, w, x, y, z, i) \
  3304. z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
  3305. w = rol(w, 30);
  3306. #define R3(v, w, x, y, z, i) \
  3307. z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
  3308. w = rol(w, 30);
  3309. #define R4(v, w, x, y, z, i) \
  3310. z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
  3311. w = rol(w, 30);
  3312. static void mg_sha1_transform(uint32_t state[5],
  3313. const unsigned char buffer[64]) {
  3314. uint32_t a, b, c, d, e;
  3315. union char64long16 block[1];
  3316. memcpy(block, buffer, 64);
  3317. a = state[0];
  3318. b = state[1];
  3319. c = state[2];
  3320. d = state[3];
  3321. e = state[4];
  3322. R0(a, b, c, d, e, 0);
  3323. R0(e, a, b, c, d, 1);
  3324. R0(d, e, a, b, c, 2);
  3325. R0(c, d, e, a, b, 3);
  3326. R0(b, c, d, e, a, 4);
  3327. R0(a, b, c, d, e, 5);
  3328. R0(e, a, b, c, d, 6);
  3329. R0(d, e, a, b, c, 7);
  3330. R0(c, d, e, a, b, 8);
  3331. R0(b, c, d, e, a, 9);
  3332. R0(a, b, c, d, e, 10);
  3333. R0(e, a, b, c, d, 11);
  3334. R0(d, e, a, b, c, 12);
  3335. R0(c, d, e, a, b, 13);
  3336. R0(b, c, d, e, a, 14);
  3337. R0(a, b, c, d, e, 15);
  3338. R1(e, a, b, c, d, 16);
  3339. R1(d, e, a, b, c, 17);
  3340. R1(c, d, e, a, b, 18);
  3341. R1(b, c, d, e, a, 19);
  3342. R2(a, b, c, d, e, 20);
  3343. R2(e, a, b, c, d, 21);
  3344. R2(d, e, a, b, c, 22);
  3345. R2(c, d, e, a, b, 23);
  3346. R2(b, c, d, e, a, 24);
  3347. R2(a, b, c, d, e, 25);
  3348. R2(e, a, b, c, d, 26);
  3349. R2(d, e, a, b, c, 27);
  3350. R2(c, d, e, a, b, 28);
  3351. R2(b, c, d, e, a, 29);
  3352. R2(a, b, c, d, e, 30);
  3353. R2(e, a, b, c, d, 31);
  3354. R2(d, e, a, b, c, 32);
  3355. R2(c, d, e, a, b, 33);
  3356. R2(b, c, d, e, a, 34);
  3357. R2(a, b, c, d, e, 35);
  3358. R2(e, a, b, c, d, 36);
  3359. R2(d, e, a, b, c, 37);
  3360. R2(c, d, e, a, b, 38);
  3361. R2(b, c, d, e, a, 39);
  3362. R3(a, b, c, d, e, 40);
  3363. R3(e, a, b, c, d, 41);
  3364. R3(d, e, a, b, c, 42);
  3365. R3(c, d, e, a, b, 43);
  3366. R3(b, c, d, e, a, 44);
  3367. R3(a, b, c, d, e, 45);
  3368. R3(e, a, b, c, d, 46);
  3369. R3(d, e, a, b, c, 47);
  3370. R3(c, d, e, a, b, 48);
  3371. R3(b, c, d, e, a, 49);
  3372. R3(a, b, c, d, e, 50);
  3373. R3(e, a, b, c, d, 51);
  3374. R3(d, e, a, b, c, 52);
  3375. R3(c, d, e, a, b, 53);
  3376. R3(b, c, d, e, a, 54);
  3377. R3(a, b, c, d, e, 55);
  3378. R3(e, a, b, c, d, 56);
  3379. R3(d, e, a, b, c, 57);
  3380. R3(c, d, e, a, b, 58);
  3381. R3(b, c, d, e, a, 59);
  3382. R4(a, b, c, d, e, 60);
  3383. R4(e, a, b, c, d, 61);
  3384. R4(d, e, a, b, c, 62);
  3385. R4(c, d, e, a, b, 63);
  3386. R4(b, c, d, e, a, 64);
  3387. R4(a, b, c, d, e, 65);
  3388. R4(e, a, b, c, d, 66);
  3389. R4(d, e, a, b, c, 67);
  3390. R4(c, d, e, a, b, 68);
  3391. R4(b, c, d, e, a, 69);
  3392. R4(a, b, c, d, e, 70);
  3393. R4(e, a, b, c, d, 71);
  3394. R4(d, e, a, b, c, 72);
  3395. R4(c, d, e, a, b, 73);
  3396. R4(b, c, d, e, a, 74);
  3397. R4(a, b, c, d, e, 75);
  3398. R4(e, a, b, c, d, 76);
  3399. R4(d, e, a, b, c, 77);
  3400. R4(c, d, e, a, b, 78);
  3401. R4(b, c, d, e, a, 79);
  3402. state[0] += a;
  3403. state[1] += b;
  3404. state[2] += c;
  3405. state[3] += d;
  3406. state[4] += e;
  3407. /* Erase working structures. The order of operations is important,
  3408. * used to ensure that compiler doesn't optimize those out. */
  3409. memset(block, 0, sizeof(block));
  3410. a = b = c = d = e = 0;
  3411. (void) a;
  3412. (void) b;
  3413. (void) c;
  3414. (void) d;
  3415. (void) e;
  3416. }
  3417. void mg_sha1_init(mg_sha1_ctx *context) {
  3418. context->state[0] = 0x67452301;
  3419. context->state[1] = 0xEFCDAB89;
  3420. context->state[2] = 0x98BADCFE;
  3421. context->state[3] = 0x10325476;
  3422. context->state[4] = 0xC3D2E1F0;
  3423. context->count[0] = context->count[1] = 0;
  3424. }
  3425. void mg_sha1_update(mg_sha1_ctx *context, const unsigned char *data,
  3426. size_t len) {
  3427. size_t i, j;
  3428. j = context->count[0];
  3429. if ((context->count[0] += (uint32_t) len << 3) < j) context->count[1]++;
  3430. context->count[1] += (uint32_t) (len >> 29);
  3431. j = (j >> 3) & 63;
  3432. if ((j + len) > 63) {
  3433. memcpy(&context->buffer[j], data, (i = 64 - j));
  3434. mg_sha1_transform(context->state, context->buffer);
  3435. for (; i + 63 < len; i += 64) {
  3436. mg_sha1_transform(context->state, &data[i]);
  3437. }
  3438. j = 0;
  3439. } else
  3440. i = 0;
  3441. memcpy(&context->buffer[j], &data[i], len - i);
  3442. }
  3443. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *context) {
  3444. unsigned i;
  3445. unsigned char finalcount[8], c;
  3446. for (i = 0; i < 8; i++) {
  3447. finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >>
  3448. ((3 - (i & 3)) * 8)) &
  3449. 255);
  3450. }
  3451. c = 0200;
  3452. mg_sha1_update(context, &c, 1);
  3453. while ((context->count[0] & 504) != 448) {
  3454. c = 0000;
  3455. mg_sha1_update(context, &c, 1);
  3456. }
  3457. mg_sha1_update(context, finalcount, 8);
  3458. for (i = 0; i < 20; i++) {
  3459. digest[i] =
  3460. (unsigned char) ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
  3461. }
  3462. memset(context, '\0', sizeof(*context));
  3463. memset(&finalcount, '\0', sizeof(finalcount));
  3464. }
  3465. #ifdef MG_ENABLE_LINES
  3466. #line 1 "src/sntp.c"
  3467. #endif
  3468. #define SNTP_TIME_OFFSET 2208988800U // (1970 - 1900) in seconds
  3469. #define SNTP_MAX_FRAC 4294967295.0 // 2 ** 32 - 1
  3470. static int64_t gettimestamp(const uint32_t *data) {
  3471. uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
  3472. if (sec) sec -= SNTP_TIME_OFFSET;
  3473. return ((int64_t) sec) * 1000 + (int64_t) (frac / SNTP_MAX_FRAC * 1000.0);
  3474. }
  3475. int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
  3476. int64_t res = -1;
  3477. int mode = len > 0 ? buf[0] & 7 : 0;
  3478. int version = len > 0 ? (buf[0] >> 3) & 7 : 0;
  3479. if (len < 48) {
  3480. MG_ERROR(("%s", "corrupt packet"));
  3481. } else if (mode != 4 && mode != 5) {
  3482. MG_ERROR(("%s", "not a server reply"));
  3483. } else if (buf[1] == 0) {
  3484. MG_ERROR(("%s", "server sent a kiss of death"));
  3485. } else if (version == 4 || version == 3) {
  3486. // int64_t ref = gettimestamp((uint32_t *) &buf[16]);
  3487. int64_t t0 = gettimestamp((uint32_t *) &buf[24]);
  3488. int64_t t1 = gettimestamp((uint32_t *) &buf[32]);
  3489. int64_t t2 = gettimestamp((uint32_t *) &buf[40]);
  3490. int64_t t3 = (int64_t) mg_millis();
  3491. int64_t delta = (t3 - t0) - (t2 - t1);
  3492. MG_DEBUG(("%lld %lld %lld %lld delta:%lld", t0, t1, t2, t3, delta));
  3493. res = t2 + delta / 2;
  3494. } else {
  3495. MG_ERROR(("unexpected version: %d", version));
  3496. }
  3497. return res;
  3498. }
  3499. static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
  3500. if (ev == MG_EV_READ) {
  3501. int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
  3502. if (milliseconds > 0) {
  3503. mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
  3504. MG_VERBOSE(("%u.%u", (unsigned) (milliseconds / 1000),
  3505. (unsigned) (milliseconds % 1000)));
  3506. }
  3507. mg_iobuf_del(&c->recv, 0, c->recv.len); // Free receive buffer
  3508. } else if (ev == MG_EV_CONNECT) {
  3509. mg_sntp_request(c);
  3510. } else if (ev == MG_EV_CLOSE) {
  3511. }
  3512. (void) fnd;
  3513. (void) evd;
  3514. }
  3515. void mg_sntp_request(struct mg_connection *c) {
  3516. if (c->is_resolving) {
  3517. MG_ERROR(("%lu wait until resolved", c->id));
  3518. } else {
  3519. int64_t now = (int64_t) mg_millis(); // Use int64_t, for vc98
  3520. uint8_t buf[48] = {0};
  3521. uint32_t *t = (uint32_t *) &buf[40];
  3522. double frac = ((double) (now % 1000)) / 1000.0 * SNTP_MAX_FRAC;
  3523. buf[0] = (0 << 6) | (4 << 3) | 3;
  3524. t[0] = mg_htonl((uint32_t) (now / 1000) + SNTP_TIME_OFFSET);
  3525. t[1] = mg_htonl((uint32_t) frac);
  3526. mg_send(c, buf, sizeof(buf));
  3527. }
  3528. }
  3529. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  3530. mg_event_handler_t fn, void *fnd) {
  3531. struct mg_connection *c = NULL;
  3532. if (url == NULL) url = "udp://time.google.com:123";
  3533. if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) c->pfn = sntp_cb;
  3534. return c;
  3535. }
  3536. #ifdef MG_ENABLE_LINES
  3537. #line 1 "src/sock.c"
  3538. #endif
  3539. #if MG_ENABLE_SOCKET
  3540. #if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  3541. typedef unsigned long nfds_t;
  3542. #define MG_SOCK_ERRNO WSAGetLastError()
  3543. #if defined(_MSC_VER)
  3544. #pragma comment(lib, "ws2_32.lib")
  3545. #define alloca(a) _alloca(a)
  3546. #endif
  3547. #define poll(a, b, c) WSAPoll((a), (b), (c))
  3548. #ifndef SO_EXCLUSIVEADDRUSE
  3549. #define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
  3550. #endif
  3551. #elif MG_ARCH == MG_ARCH_FREERTOS_TCP
  3552. #define MG_SOCK_ERRNO errno
  3553. typedef Socket_t SOCKET;
  3554. #define INVALID_SOCKET FREERTOS_INVALID_SOCKET
  3555. #elif MG_ARCH == MG_ARCH_TIRTOS
  3556. #define MG_SOCK_ERRNO errno
  3557. #define closesocket(x) close(x)
  3558. #else
  3559. #define MG_SOCK_ERRNO errno
  3560. #ifndef closesocket
  3561. #define closesocket(x) close(x)
  3562. #endif
  3563. #define INVALID_SOCKET (-1)
  3564. typedef int SOCKET;
  3565. #endif
  3566. #define FD(c_) ((SOCKET) (size_t) (c_)->fd)
  3567. #define S2PTR(s_) ((void *) (size_t) (s_))
  3568. #ifndef MSG_NONBLOCKING
  3569. #define MSG_NONBLOCKING 0
  3570. #endif
  3571. #ifndef AF_INET6
  3572. #define AF_INET6 10
  3573. #endif
  3574. union usa {
  3575. struct sockaddr sa;
  3576. struct sockaddr_in sin;
  3577. #if MG_ENABLE_IPV6
  3578. struct sockaddr_in6 sin6;
  3579. #endif
  3580. };
  3581. static socklen_t tousa(struct mg_addr *a, union usa *usa) {
  3582. socklen_t len = sizeof(usa->sin);
  3583. memset(usa, 0, sizeof(*usa));
  3584. usa->sin.sin_family = AF_INET;
  3585. usa->sin.sin_port = a->port;
  3586. *(uint32_t *) &usa->sin.sin_addr = a->ip;
  3587. #if MG_ENABLE_IPV6
  3588. if (a->is_ip6) {
  3589. usa->sin.sin_family = AF_INET6;
  3590. usa->sin6.sin6_port = a->port;
  3591. memcpy(&usa->sin6.sin6_addr, a->ip6, sizeof(a->ip6));
  3592. len = sizeof(usa->sin6);
  3593. }
  3594. #endif
  3595. return len;
  3596. }
  3597. static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
  3598. a->is_ip6 = is_ip6;
  3599. a->port = usa->sin.sin_port;
  3600. memcpy(&a->ip, &usa->sin.sin_addr, sizeof(a->ip));
  3601. #if MG_ENABLE_IPV6
  3602. if (is_ip6) {
  3603. memcpy(a->ip6, &usa->sin6.sin6_addr, sizeof(a->ip6));
  3604. a->port = usa->sin6.sin6_port;
  3605. }
  3606. #endif
  3607. }
  3608. bool mg_sock_would_block(void);
  3609. bool mg_sock_would_block(void) {
  3610. int err = MG_SOCK_ERRNO;
  3611. return err == EINPROGRESS || err == EWOULDBLOCK
  3612. #ifndef WINCE
  3613. || err == EAGAIN || err == EINTR
  3614. #endif
  3615. #if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  3616. || err == WSAEINTR || err == WSAEWOULDBLOCK
  3617. #endif
  3618. ;
  3619. }
  3620. bool mg_sock_conn_reset(void);
  3621. bool mg_sock_conn_reset(void) {
  3622. int err = MG_SOCK_ERRNO;
  3623. #if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  3624. return err == WSAECONNRESET;
  3625. #else
  3626. return err == EPIPE || err == ECONNRESET;
  3627. #endif
  3628. }
  3629. static void setlocaddr(SOCKET fd, struct mg_addr *addr) {
  3630. union usa usa;
  3631. socklen_t n = sizeof(usa);
  3632. if (getsockname(fd, &usa.sa, &n) == 0) {
  3633. tomgaddr(&usa, addr, n != sizeof(usa.sin));
  3634. }
  3635. }
  3636. static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
  3637. if (n == 0) {
  3638. // Do nothing
  3639. } else if (n < 0) {
  3640. c->is_closing = 1; // Termination. Don't call mg_error(): #1529
  3641. } else if (n > 0) {
  3642. if (c->is_hexdumping) {
  3643. union usa usa;
  3644. char t1[50], t2[50];
  3645. socklen_t slen = sizeof(usa.sin);
  3646. struct mg_addr a;
  3647. memset(&usa, 0, sizeof(usa));
  3648. memset(&a, 0, sizeof(a));
  3649. if (getsockname(FD(c), &usa.sa, &slen) < 0) (void) 0; // Ignore result
  3650. tomgaddr(&usa, &a, c->rem.is_ip6);
  3651. MG_INFO(("\n-- %lu %s %s %s %s %ld", c->id,
  3652. mg_straddr(&a, t1, sizeof(t1)), r ? "<-" : "->",
  3653. mg_straddr(&c->rem, t2, sizeof(t2)), c->label, n));
  3654. mg_hexdump(buf, (size_t) n);
  3655. }
  3656. if (r) {
  3657. struct mg_str evd = mg_str_n(buf, (size_t) n);
  3658. c->recv.len += (size_t) n;
  3659. mg_call(c, MG_EV_READ, &evd);
  3660. } else {
  3661. mg_iobuf_del(&c->send, 0, (size_t) n);
  3662. // if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
  3663. if (c->send.len == 0) {
  3664. MG_EPOLL_MOD(c, 0);
  3665. }
  3666. mg_call(c, MG_EV_WRITE, &n);
  3667. }
  3668. }
  3669. }
  3670. static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
  3671. long n;
  3672. if (c->is_udp) {
  3673. union usa usa;
  3674. socklen_t slen = tousa(&c->rem, &usa);
  3675. n = sendto(FD(c), (char *) buf, len, 0, &usa.sa, slen);
  3676. if (n > 0) setlocaddr(FD(c), &c->loc);
  3677. } else {
  3678. n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
  3679. #if MG_ARCH == MG_ARCH_RTX
  3680. if (n == BSD_EWOULDBLOCK) return 0;
  3681. #endif
  3682. }
  3683. return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
  3684. }
  3685. bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
  3686. if (c->is_udp) {
  3687. long n = mg_sock_send(c, buf, len);
  3688. MG_DEBUG(("%lu %p %d:%d %ld err %d", c->id, c->fd, (int) c->send.len,
  3689. (int) c->recv.len, n, MG_SOCK_ERRNO));
  3690. iolog(c, (char *) buf, n, false);
  3691. return n > 0;
  3692. } else {
  3693. return mg_iobuf_add(&c->send, c->send.len, buf, len);
  3694. }
  3695. }
  3696. static void mg_set_non_blocking_mode(SOCKET fd) {
  3697. #if defined(MG_CUSTOM_NONBLOCK)
  3698. MG_CUSTOM_NONBLOCK(fd);
  3699. #elif MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  3700. unsigned long on = 1;
  3701. ioctlsocket(fd, FIONBIO, &on);
  3702. #elif MG_ARCH == MG_ARCH_RTX
  3703. unsigned long on = 1;
  3704. ioctlsocket(fd, FIONBIO, &on);
  3705. #elif MG_ARCH == MG_ARCH_FREERTOS_TCP
  3706. const BaseType_t off = 0;
  3707. if (setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off)) != 0) (void) 0;
  3708. if (setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)) != 0) (void) 0;
  3709. #elif MG_ARCH == MG_ARCH_FREERTOS_LWIP || MG_ARCH == MG_ARCH_RTX_LWIP
  3710. lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
  3711. #elif MG_ARCH == MG_ARCH_AZURERTOS
  3712. fcntl(fd, F_SETFL, O_NONBLOCK);
  3713. #elif MG_ARCH == MG_ARCH_TIRTOS
  3714. int val = 0;
  3715. setsockopt(fd, 0, SO_BLOCKING, &val, sizeof(val));
  3716. int status = 0;
  3717. int res = SockStatus(fd, FDSTATUS_SEND, &status);
  3718. if (res == 0 && status > 0) {
  3719. val = status / 2;
  3720. int val_size = sizeof(val);
  3721. res = SockSet(fd, SOL_SOCKET, SO_SNDLOWAT, &val, val_size);
  3722. }
  3723. #else
  3724. fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); // Non-blocking mode
  3725. fcntl(fd, F_SETFD, FD_CLOEXEC); // Set close-on-exec
  3726. #endif
  3727. }
  3728. bool mg_open_listener(struct mg_connection *c, const char *url) {
  3729. SOCKET fd = INVALID_SOCKET;
  3730. bool success = false;
  3731. c->loc.port = mg_htons(mg_url_port(url));
  3732. if (!mg_aton(mg_url_host(url), &c->loc)) {
  3733. MG_ERROR(("invalid listening URL: %s", url));
  3734. } else {
  3735. union usa usa;
  3736. socklen_t slen = tousa(&c->loc, &usa);
  3737. int on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET;
  3738. int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
  3739. int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
  3740. (void) on;
  3741. if ((fd = socket(af, type, proto)) == INVALID_SOCKET) {
  3742. MG_ERROR(("socket: %d", MG_SOCK_ERRNO));
  3743. #if ((MG_ARCH == MG_ARCH_WIN32) || (MG_ARCH == MG_ARCH_UNIX) || \
  3744. (defined(LWIP_SOCKET) && SO_REUSE == 1))
  3745. } else if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
  3746. sizeof(on)) != 0) {
  3747. // 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
  3748. // SO_REUSEADDR on UNIX and Windows is different. On Windows,
  3749. // SO_REUSEADDR allows to bind a socket to a port without error even
  3750. // if the port is already open by another program. This is not the
  3751. // behavior SO_REUSEADDR was designed for, and leads to hard-to-track
  3752. // failure scenarios. Therefore, SO_REUSEADDR was disabled on Windows
  3753. // unless SO_EXCLUSIVEADDRUSE is supported and set on a socket.
  3754. // 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by
  3755. // defining
  3756. // SO_REUSE (in lwipopts.h), otherwise the code below will compile
  3757. // but won't work! (setsockopt will return EINVAL)
  3758. MG_ERROR(("reuseaddr: %d", MG_SOCK_ERRNO));
  3759. #endif
  3760. #if MG_ARCH == MG_ARCH_WIN32 && !defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
  3761. } else if (setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &on,
  3762. sizeof(on)) != 0) {
  3763. // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
  3764. MG_ERROR(("exclusiveaddruse: %d", MG_SOCK_ERRNO));
  3765. #endif
  3766. } else if (bind(fd, &usa.sa, slen) != 0) {
  3767. MG_ERROR(("bind: %d", MG_SOCK_ERRNO));
  3768. } else if ((type == SOCK_STREAM &&
  3769. listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) != 0)) {
  3770. // NOTE(lsm): FreeRTOS uses backlog value as a connection limit
  3771. // In case port was set to 0, get the real port number
  3772. MG_ERROR(("listen: %d", MG_SOCK_ERRNO));
  3773. } else {
  3774. setlocaddr(fd, &c->loc);
  3775. mg_set_non_blocking_mode(fd);
  3776. c->fd = S2PTR(fd);
  3777. MG_EPOLL_ADD(c);
  3778. success = true;
  3779. }
  3780. }
  3781. if (success == false && fd != INVALID_SOCKET) closesocket(fd);
  3782. return success;
  3783. }
  3784. static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
  3785. long n = 0;
  3786. if (c->is_udp) {
  3787. union usa usa;
  3788. socklen_t slen = tousa(&c->rem, &usa);
  3789. n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
  3790. if (n > 0) tomgaddr(&usa, &c->rem, slen != sizeof(usa.sin));
  3791. } else {
  3792. n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
  3793. char **ppOutput;
  3794. //utf8_to_unicode((char *) buf, ppOutput);
  3795. }
  3796. return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
  3797. }
  3798. // NOTE(lsm): do only one iteration of reads, cause some systems
  3799. // (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
  3800. static void read_conn(struct mg_connection *c) {
  3801. long n = -1;
  3802. if (c->recv.len >= MG_MAX_RECV_SIZE) {
  3803. mg_error(c, "max_recv_buf_size reached");
  3804. } else if (c->recv.size <= c->recv.len &&
  3805. !mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE)) {
  3806. mg_error(c, "oom");
  3807. } else {
  3808. char *buf = (char *) &c->recv.buf[c->recv.len];
  3809. size_t len = c->recv.size - c->recv.len;
  3810. n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_sock_recv(c, buf, len);
  3811. MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
  3812. (long) c->send.len, (long) c->send.size, (long) c->recv.len,
  3813. (long) c->recv.size, n, MG_SOCK_ERRNO));
  3814. iolog(c, buf, n, true);
  3815. }
  3816. }
  3817. static void write_conn(struct mg_connection *c) {
  3818. char *buf = (char *) c->send.buf;
  3819. size_t len = c->send.len;
  3820. long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_sock_send(c, buf, len);
  3821. MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
  3822. (long) c->send.len, (long) c->send.size, (long) c->recv.len,
  3823. (long) c->recv.size, n, MG_SOCK_ERRNO));
  3824. iolog(c, buf, n, false);
  3825. }
  3826. static void close_conn(struct mg_connection *c) {
  3827. if (FD(c) != INVALID_SOCKET) {
  3828. #if MG_ENABLE_EPOLL
  3829. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_DEL, FD(c), NULL);
  3830. #endif
  3831. closesocket(FD(c));
  3832. #if MG_ARCH == MG_ARCH_FREERTOS_TCP
  3833. FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL);
  3834. #endif
  3835. }
  3836. mg_close_conn(c);
  3837. }
  3838. static void connect_conn(struct mg_connection *c) {
  3839. union usa usa;
  3840. socklen_t n = sizeof(usa);
  3841. // Use getpeername() to test whether we have connected
  3842. if (getpeername(FD(c), &usa.sa, &n) == 0) {
  3843. c->is_connecting = 0;
  3844. mg_call(c, MG_EV_CONNECT, NULL);
  3845. MG_EPOLL_MOD(c, 0);
  3846. if (c->is_tls_hs) mg_tls_handshake(c);
  3847. } else {
  3848. mg_error(c, "socket error");
  3849. }
  3850. }
  3851. static void setsockopts(struct mg_connection *c) {
  3852. #if MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS || \
  3853. MG_ARCH == MG_ARCH_TIRTOS
  3854. (void) c;
  3855. #else
  3856. int on = 1;
  3857. #if !defined(SOL_TCP)
  3858. #define SOL_TCP IPPROTO_TCP
  3859. #endif
  3860. if (setsockopt(FD(c), SOL_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) != 0)
  3861. (void) 0;
  3862. if (setsockopt(FD(c), SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) !=
  3863. 0)
  3864. (void) 0;
  3865. #endif
  3866. }
  3867. void mg_connect_resolved(struct mg_connection *c) {
  3868. // char buf[40];
  3869. int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
  3870. int rc, af = c->rem.is_ip6 ? AF_INET6 : AF_INET;
  3871. // mg_straddr(&c->rem, buf, sizeof(buf));
  3872. c->fd = S2PTR(socket(af, type, 0));
  3873. c->is_resolving = 0;
  3874. if (FD(c) == INVALID_SOCKET) {
  3875. mg_error(c, "socket(): %d", MG_SOCK_ERRNO);
  3876. } else if (c->is_udp) {
  3877. MG_EPOLL_ADD(c);
  3878. mg_call(c, MG_EV_RESOLVE, NULL);
  3879. mg_call(c, MG_EV_CONNECT, NULL);
  3880. } else {
  3881. union usa usa;
  3882. socklen_t slen = tousa(&c->rem, &usa);
  3883. mg_set_non_blocking_mode(FD(c));
  3884. setsockopts(c);
  3885. MG_EPOLL_ADD(c);
  3886. mg_call(c, MG_EV_RESOLVE, NULL);
  3887. if ((rc = connect(FD(c), &usa.sa, slen)) == 0) {
  3888. mg_call(c, MG_EV_CONNECT, NULL);
  3889. } else if (mg_sock_would_block()) {
  3890. MG_DEBUG(("%lu %p -> %x:%hu pend", c->id, c->fd, mg_ntohl(c->rem.ip),
  3891. mg_ntohs(c->rem.port)));
  3892. c->is_connecting = 1;
  3893. } else {
  3894. mg_error(c, "connect: %d", MG_SOCK_ERRNO);
  3895. }
  3896. }
  3897. }
  3898. static SOCKET raccept(SOCKET sock, union usa *usa, socklen_t len) {
  3899. SOCKET s = INVALID_SOCKET;
  3900. do {
  3901. memset(usa, 0, sizeof(*usa));
  3902. s = accept(sock, &usa->sa, &len);
  3903. } while (s == INVALID_SOCKET && errno == EINTR);
  3904. return s;
  3905. }
  3906. static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
  3907. struct mg_connection *c = NULL;
  3908. union usa usa;
  3909. socklen_t sa_len = sizeof(usa);
  3910. SOCKET fd = raccept(FD(lsn), &usa, sa_len);
  3911. if (fd == INVALID_SOCKET) {
  3912. #if MG_ARCH == MG_ARCH_AZURERTOS
  3913. // AzureRTOS, in non-block socket mode can mark listening socket readable
  3914. // even it is not. See comment for 'select' func implementation in
  3915. // nx_bsd.c That's not an error, just should try later
  3916. if (MG_SOCK_ERRNO != EAGAIN)
  3917. #endif
  3918. MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
  3919. #if (MG_ARCH != MG_ARCH_WIN32) && (MG_ARCH != MG_ARCH_FREERTOS_TCP) && \
  3920. (MG_ARCH != MG_ARCH_TIRTOS) && !(MG_ENABLE_POLL)
  3921. } else if ((long) fd >= FD_SETSIZE) {
  3922. MG_ERROR(("%ld > %ld", (long) fd, (long) FD_SETSIZE));
  3923. closesocket(fd);
  3924. #endif
  3925. } else if ((c = mg_alloc_conn(mgr)) == NULL) {
  3926. MG_ERROR(("%lu OOM", lsn->id));
  3927. closesocket(fd);
  3928. } else {
  3929. // char buf[40];
  3930. tomgaddr(&usa, &c->rem, sa_len != sizeof(usa.sin));
  3931. // mg_straddr(&c->rem, buf, sizeof(buf));
  3932. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  3933. c->fd = S2PTR(fd);
  3934. MG_EPOLL_ADD(c);
  3935. mg_set_non_blocking_mode(FD(c));
  3936. setsockopts(c);
  3937. c->is_accepted = 1;
  3938. c->is_hexdumping = lsn->is_hexdumping;
  3939. c->loc = lsn->loc;
  3940. c->pfn = lsn->pfn;
  3941. c->pfn_data = lsn->pfn_data;
  3942. c->fn = lsn->fn;
  3943. c->fn_data = lsn->fn_data;
  3944. MG_DEBUG(("%lu %p accepted %x.%hu -> %x.%hu", c->id, c->fd,
  3945. mg_ntohl(c->rem.ip), mg_ntohs(c->rem.port), mg_ntohl(c->loc.ip),
  3946. mg_ntohs(c->loc.port)));
  3947. mg_call(c, MG_EV_OPEN, NULL);
  3948. mg_call(c, MG_EV_ACCEPT, NULL);
  3949. }
  3950. }
  3951. static bool mg_socketpair(SOCKET sp[2], union usa usa[2], bool udp) {
  3952. SOCKET sock;
  3953. socklen_t n = sizeof(usa[0].sin);
  3954. bool success = false;
  3955. sock = sp[0] = sp[1] = INVALID_SOCKET;
  3956. (void) memset(&usa[0], 0, sizeof(usa[0]));
  3957. usa[0].sin.sin_family = AF_INET;
  3958. *(uint32_t *) &usa->sin.sin_addr = mg_htonl(0x7f000001U); // 127.0.0.1
  3959. usa[1] = usa[0];
  3960. if (udp && (sp[0] = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET &&
  3961. (sp[1] = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET &&
  3962. bind(sp[0], &usa[0].sa, n) == 0 && bind(sp[1], &usa[1].sa, n) == 0 &&
  3963. getsockname(sp[0], &usa[0].sa, &n) == 0 &&
  3964. getsockname(sp[1], &usa[1].sa, &n) == 0 &&
  3965. connect(sp[0], &usa[1].sa, n) == 0 &&
  3966. connect(sp[1], &usa[0].sa, n) == 0) {
  3967. success = true;
  3968. } else if (!udp &&
  3969. (sock = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET &&
  3970. bind(sock, &usa[0].sa, n) == 0 &&
  3971. listen(sock, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0 &&
  3972. getsockname(sock, &usa[0].sa, &n) == 0 &&
  3973. (sp[0] = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET &&
  3974. connect(sp[0], &usa[0].sa, n) == 0 &&
  3975. (sp[1] = raccept(sock, &usa[1], n)) != INVALID_SOCKET) {
  3976. success = true;
  3977. }
  3978. if (success) {
  3979. mg_set_non_blocking_mode(sp[1]);
  3980. } else {
  3981. if (sp[0] != INVALID_SOCKET) closesocket(sp[0]);
  3982. if (sp[1] != INVALID_SOCKET) closesocket(sp[1]);
  3983. sp[0] = sp[1] = INVALID_SOCKET;
  3984. }
  3985. if (sock != INVALID_SOCKET) closesocket(sock);
  3986. return success;
  3987. }
  3988. int mg_mkpipe(struct mg_mgr *mgr, mg_event_handler_t fn, void *fn_data,
  3989. bool udp) {
  3990. union usa usa[2];
  3991. SOCKET sp[2] = {INVALID_SOCKET, INVALID_SOCKET};
  3992. struct mg_connection *c = NULL;
  3993. if (!mg_socketpair(sp, usa, udp)) {
  3994. MG_ERROR(("Cannot create socket pair"));
  3995. } else if ((c = mg_wrapfd(mgr, (int) sp[1], fn, fn_data)) == NULL) {
  3996. closesocket(sp[0]);
  3997. closesocket(sp[1]);
  3998. sp[0] = sp[1] = INVALID_SOCKET;
  3999. } else {
  4000. tomgaddr(&usa[0], &c->rem, false);
  4001. MG_DEBUG(("%lu %p pipe %lu", c->id, c->fd, (unsigned long) sp[0]));
  4002. }
  4003. return (int) sp[0];
  4004. }
  4005. static bool can_read(const struct mg_connection *c) {
  4006. return c->is_full == false;
  4007. }
  4008. static bool can_write(const struct mg_connection *c) {
  4009. return c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0);
  4010. }
  4011. static bool skip_iotest(const struct mg_connection *c) {
  4012. return (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) ||
  4013. (can_read(c) == false && can_write(c) == false);
  4014. }
  4015. static void mg_iotest(struct mg_mgr *mgr, int ms) {
  4016. #if MG_ARCH == MG_ARCH_FREERTOS_TCP
  4017. struct mg_connection *c;
  4018. for (c = mgr->conns; c != NULL; c = c->next) {
  4019. c->is_readable = c->is_writable = 0;
  4020. if (skip_iotest(c)) continue;
  4021. if (can_read(c))
  4022. FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT);
  4023. if (can_write(c)) FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_WRITE);
  4024. }
  4025. FreeRTOS_select(mgr->ss, pdMS_TO_TICKS(ms));
  4026. for (c = mgr->conns; c != NULL; c = c->next) {
  4027. EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss);
  4028. c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1 : 0;
  4029. c->is_writable = bits & eSELECT_WRITE ? 1 : 0;
  4030. FreeRTOS_FD_CLR(c->fd, mgr->ss,
  4031. eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE);
  4032. }
  4033. #elif MG_ENABLE_EPOLL
  4034. size_t max = 1;
  4035. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  4036. c->is_readable = c->is_writable = 0;
  4037. if (mg_tls_pending(c) > 0) ms = 1, c->is_readable = 1;
  4038. if (can_write(c)) MG_EPOLL_MOD(c, 1);
  4039. max++;
  4040. }
  4041. struct epoll_event *evs = (struct epoll_event *) alloca(max * sizeof(evs[0]));
  4042. int n = epoll_wait(mgr->epoll_fd, evs, (int) max, ms);
  4043. for (int i = 0; i < n; i++) {
  4044. struct mg_connection *c = (struct mg_connection *) evs[i].data.ptr;
  4045. if (evs[i].events & EPOLLERR) {
  4046. mg_error(c, "socket error");
  4047. } else if (c->is_readable == 0) {
  4048. bool rd = evs[i].events & (EPOLLIN | EPOLLHUP);
  4049. bool wr = evs[i].events & EPOLLOUT;
  4050. c->is_readable = can_read(c) && rd ? 1U : 0;
  4051. c->is_writable = can_write(c) && wr ? 1U : 0;
  4052. }
  4053. }
  4054. (void) skip_iotest;
  4055. #elif MG_ENABLE_POLL
  4056. nfds_t n = 0;
  4057. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) n++;
  4058. struct pollfd *fds = (struct pollfd *) alloca(n * sizeof(fds[0]));
  4059. memset(fds, 0, n * sizeof(fds[0]));
  4060. n = 0;
  4061. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  4062. c->is_readable = c->is_writable = 0;
  4063. if (skip_iotest(c)) {
  4064. // Socket not valid, ignore
  4065. } else if (mg_tls_pending(c) > 0) {
  4066. ms = 1; // Don't wait if TLS is ready
  4067. } else {
  4068. fds[n].fd = FD(c);
  4069. if (can_read(c)) fds[n].events |= POLLIN;
  4070. if (can_write(c)) fds[n].events |= POLLOUT;
  4071. n++;
  4072. }
  4073. }
  4074. // MG_INFO(("poll n=%d ms=%d", (int) n, ms));
  4075. if (poll(fds, n, ms) < 0) {
  4076. #if MG_ARCH == MG_ARCH_WIN32
  4077. if (n == 0) Sleep(ms); // On Windows, poll fails if no sockets
  4078. #endif
  4079. memset(fds, 0, n * sizeof(fds[0]));
  4080. }
  4081. n = 0;
  4082. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  4083. if (skip_iotest(c)) {
  4084. // Socket not valid, ignore
  4085. } else if (mg_tls_pending(c) > 0) {
  4086. c->is_readable = 1;
  4087. } else {
  4088. if (fds[n].revents & POLLERR) {
  4089. mg_error(c, "socket error");
  4090. } else {
  4091. c->is_readable =
  4092. (unsigned) (fds[n].revents & (POLLIN | POLLHUP) ? 1 : 0);
  4093. c->is_writable = (unsigned) (fds[n].revents & POLLOUT ? 1 : 0);
  4094. }
  4095. n++;
  4096. }
  4097. }
  4098. #else
  4099. struct timeval tv = {ms / 1000, (ms % 1000) * 1000}, tv_zero = {0, 0};
  4100. struct mg_connection *c;
  4101. fd_set rset, wset, eset;
  4102. SOCKET maxfd = 0;
  4103. int rc;
  4104. FD_ZERO(&rset);
  4105. FD_ZERO(&wset);
  4106. FD_ZERO(&eset);
  4107. for (c = mgr->conns; c != NULL; c = c->next) {
  4108. c->is_readable = c->is_writable = 0;
  4109. if (skip_iotest(c)) continue;
  4110. FD_SET(FD(c), &eset);
  4111. if (can_read(c)) FD_SET(FD(c), &rset);
  4112. if (can_write(c)) FD_SET(FD(c), &wset);
  4113. if (mg_tls_pending(c) > 0) tv = tv_zero;
  4114. if (FD(c) > maxfd) maxfd = FD(c);
  4115. }
  4116. if ((rc = select((int) maxfd + 1, &rset, &wset, &eset, &tv)) < 0) {
  4117. #if MG_ARCH == MG_ARCH_WIN32
  4118. if (maxfd == 0) Sleep(ms); // On Windows, select fails if no sockets
  4119. #else
  4120. MG_ERROR(("select: %d %d", rc, MG_SOCK_ERRNO));
  4121. #endif
  4122. FD_ZERO(&rset);
  4123. FD_ZERO(&wset);
  4124. FD_ZERO(&eset);
  4125. }
  4126. for (c = mgr->conns; c != NULL; c = c->next) {
  4127. if (FD(c) != INVALID_SOCKET && FD_ISSET(FD(c), &eset)) {
  4128. mg_error(c, "socket error");
  4129. } else {
  4130. c->is_readable = FD(c) != INVALID_SOCKET && FD_ISSET(FD(c), &rset);
  4131. c->is_writable = FD(c) != INVALID_SOCKET && FD_ISSET(FD(c), &wset);
  4132. if (mg_tls_pending(c) > 0) c->is_readable = 1;
  4133. }
  4134. }
  4135. #endif
  4136. }
  4137. void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
  4138. struct mg_connection *c, *tmp;
  4139. uint64_t now;
  4140. mg_iotest(mgr, ms);
  4141. now = mg_millis();
  4142. mg_timer_poll(&mgr->timers, now);
  4143. for (c = mgr->conns; c != NULL; c = tmp) {
  4144. bool is_resp = c->is_resp;
  4145. tmp = c->next;
  4146. mg_call(c, MG_EV_POLL, &now);
  4147. if (is_resp && !c->is_resp) {
  4148. struct mg_str fake = mg_str_n("", 0);
  4149. mg_call(c, MG_EV_READ, &fake);
  4150. }
  4151. MG_VERBOSE(("%lu %c%c %c%c%c%c%c", c->id, c->is_readable ? 'r' : '-',
  4152. c->is_writable ? 'w' : '-', c->is_tls ? 'T' : 't',
  4153. c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
  4154. c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
  4155. if (c->is_resolving || c->is_closing) {
  4156. // Do nothing
  4157. } else if (c->is_listening && c->is_udp == 0) {
  4158. if (c->is_readable) accept_conn(mgr, c);
  4159. } else if (c->is_connecting) {
  4160. if (c->is_readable || c->is_writable) connect_conn(c);
  4161. } else if (c->is_tls_hs) {
  4162. if ((c->is_readable || c->is_writable)) mg_tls_handshake(c);
  4163. } else {
  4164. if (c->is_readable) read_conn(c);
  4165. if (c->is_writable) write_conn(c);
  4166. }
  4167. if (c->is_draining && c->send.len == 0) c->is_closing = 1;
  4168. if (c->is_closing) close_conn(c);
  4169. }
  4170. }
  4171. #endif
  4172. #ifdef MG_ENABLE_LINES
  4173. #line 1 "src/ssi.c"
  4174. #endif
  4175. #ifndef MG_MAX_SSI_DEPTH
  4176. #define MG_MAX_SSI_DEPTH 5
  4177. #endif
  4178. #ifndef MG_SSI_BUFSIZ
  4179. #define MG_SSI_BUFSIZ 1024
  4180. #endif
  4181. #if MG_ENABLE_SSI
  4182. static char *mg_ssi(const char *path, const char *root, int depth) {
  4183. struct mg_iobuf b = {NULL, 0, 0, MG_IO_SIZE};
  4184. FILE *fp = fopen(path, "rb");
  4185. if (fp != NULL) {
  4186. char buf[MG_SSI_BUFSIZ], arg[sizeof(buf)];
  4187. int ch, intag = 0;
  4188. size_t len = 0;
  4189. buf[0] = arg[0] = '\0';
  4190. while ((ch = fgetc(fp)) != EOF) {
  4191. if (intag && ch == '>' && buf[len - 1] == '-' && buf[len - 2] == '-') {
  4192. buf[len++] = (char) (ch & 0xff);
  4193. buf[len] = '\0';
  4194. if (sscanf(buf, "<!--#include file=\"%[^\"]", arg)) {
  4195. char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10],
  4196. *p = (char *) path + strlen(path), *data;
  4197. while (p > path && p[-1] != MG_DIRSEP && p[-1] != '/') p--;
  4198. mg_snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
  4199. if (depth < MG_MAX_SSI_DEPTH &&
  4200. (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
  4201. mg_iobuf_add(&b, b.len, data, strlen(data));
  4202. free(data);
  4203. } else {
  4204. MG_ERROR(("%s: file=%s error or too deep", path, arg));
  4205. }
  4206. } else if (sscanf(buf, "<!--#include virtual=\"%[^\"]", arg)) {
  4207. char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10], *data;
  4208. mg_snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
  4209. if (depth < MG_MAX_SSI_DEPTH &&
  4210. (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
  4211. mg_iobuf_add(&b, b.len, data, strlen(data));
  4212. free(data);
  4213. } else {
  4214. MG_ERROR(("%s: virtual=%s error or too deep", path, arg));
  4215. }
  4216. } else {
  4217. // Unknown SSI tag
  4218. MG_ERROR(("Unknown SSI tag: %.*s", (int) len, buf));
  4219. mg_iobuf_add(&b, b.len, buf, len);
  4220. }
  4221. intag = 0;
  4222. len = 0;
  4223. } else if (ch == '<') {
  4224. intag = 1;
  4225. if (len > 0) mg_iobuf_add(&b, b.len, buf, len);
  4226. len = 0;
  4227. buf[len++] = (char) (ch & 0xff);
  4228. } else if (intag) {
  4229. if (len == 5 && strncmp(buf, "<!--#", 5) != 0) {
  4230. intag = 0;
  4231. } else if (len >= sizeof(buf) - 2) {
  4232. MG_ERROR(("%s: SSI tag is too large", path));
  4233. len = 0;
  4234. }
  4235. buf[len++] = (char) (ch & 0xff);
  4236. } else {
  4237. buf[len++] = (char) (ch & 0xff);
  4238. if (len >= sizeof(buf)) {
  4239. mg_iobuf_add(&b, b.len, buf, len);
  4240. len = 0;
  4241. }
  4242. }
  4243. }
  4244. if (len > 0) mg_iobuf_add(&b, b.len, buf, len);
  4245. if (b.len > 0) mg_iobuf_add(&b, b.len, "", 1); // nul-terminate
  4246. fclose(fp);
  4247. }
  4248. (void) depth;
  4249. (void) root;
  4250. return (char *) b.buf;
  4251. }
  4252. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  4253. const char *fullpath) {
  4254. const char *headers = "Content-Type: text/html; charset=utf-8\r\n";
  4255. char *data = mg_ssi(fullpath, root, 0);
  4256. mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data);
  4257. free(data);
  4258. }
  4259. #else
  4260. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  4261. const char *fullpath) {
  4262. mg_http_reply(c, 501, NULL, "SSI not enabled");
  4263. (void) root, (void) fullpath;
  4264. }
  4265. #endif
  4266. #ifdef MG_ENABLE_LINES
  4267. #line 1 "src/str.c"
  4268. #endif
  4269. struct mg_str mg_str_s(const char *s) {
  4270. struct mg_str str = {s, s == NULL ? 0 : strlen(s)};
  4271. return str;
  4272. }
  4273. struct mg_str mg_str_n(const char *s, size_t n) {
  4274. struct mg_str str = {s, n};
  4275. return str;
  4276. }
  4277. int mg_lower(const char *s) {
  4278. int c = *s;
  4279. if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
  4280. return c;
  4281. }
  4282. int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
  4283. int diff = 0;
  4284. if (len > 0) do {
  4285. diff = mg_lower(s1++) - mg_lower(s2++);
  4286. } while (diff == 0 && s1[-1] != '\0' && --len > 0);
  4287. return diff;
  4288. }
  4289. int mg_casecmp(const char *s1, const char *s2) {
  4290. return mg_ncasecmp(s1, s2, (size_t) ~0);
  4291. }
  4292. int mg_vcmp(const struct mg_str *s1, const char *s2) {
  4293. size_t n2 = strlen(s2), n1 = s1->len;
  4294. int r = strncmp(s1->ptr, s2, (n1 < n2) ? n1 : n2);
  4295. if (r == 0) return (int) (n1 - n2);
  4296. return r;
  4297. }
  4298. int mg_vcasecmp(const struct mg_str *str1, const char *str2) {
  4299. size_t n2 = strlen(str2), n1 = str1->len;
  4300. int r = mg_ncasecmp(str1->ptr, str2, (n1 < n2) ? n1 : n2);
  4301. if (r == 0) return (int) (n1 - n2);
  4302. return r;
  4303. }
  4304. struct mg_str mg_strdup(const struct mg_str s) {
  4305. struct mg_str r = {NULL, 0};
  4306. if (s.len > 0 && s.ptr != NULL) {
  4307. char *sc = (char *) calloc(1, s.len + 1);
  4308. if (sc != NULL) {
  4309. memcpy(sc, s.ptr, s.len);
  4310. sc[s.len] = '\0';
  4311. r.ptr = sc;
  4312. r.len = s.len;
  4313. }
  4314. }
  4315. return r;
  4316. }
  4317. int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
  4318. size_t i = 0;
  4319. while (i < str1.len && i < str2.len) {
  4320. int c1 = str1.ptr[i];
  4321. int c2 = str2.ptr[i];
  4322. if (c1 < c2) return -1;
  4323. if (c1 > c2) return 1;
  4324. i++;
  4325. }
  4326. if (i < str1.len) return 1;
  4327. if (i < str2.len) return -1;
  4328. return 0;
  4329. }
  4330. const char *mg_strstr(const struct mg_str haystack,
  4331. const struct mg_str needle) {
  4332. size_t i;
  4333. if (needle.len > haystack.len) return NULL;
  4334. for (i = 0; i <= haystack.len - needle.len; i++) {
  4335. if (memcmp(haystack.ptr + i, needle.ptr, needle.len) == 0) {
  4336. return haystack.ptr + i;
  4337. }
  4338. }
  4339. return NULL;
  4340. }
  4341. static bool is_space(int c) {
  4342. return c == ' ' || c == '\r' || c == '\n' || c == '\t';
  4343. }
  4344. struct mg_str mg_strstrip(struct mg_str s) {
  4345. while (s.len > 0 && is_space((int) *s.ptr)) s.ptr++, s.len--;
  4346. while (s.len > 0 && is_space((int) *(s.ptr + s.len - 1))) s.len--;
  4347. return s;
  4348. }
  4349. bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
  4350. size_t i = 0, j = 0, ni = 0, nj = 0;
  4351. if (caps) caps->ptr = NULL, caps->len = 0;
  4352. while (i < p.len || j < s.len) {
  4353. if (i < p.len && j < s.len && (p.ptr[i] == '?' || s.ptr[j] == p.ptr[i])) {
  4354. if (caps == NULL) {
  4355. } else if (p.ptr[i] == '?') {
  4356. caps->ptr = &s.ptr[j], caps->len = 1; // Finalize `?` cap
  4357. caps++, caps->ptr = NULL, caps->len = 0; // Init next cap
  4358. } else if (caps->ptr != NULL && caps->len == 0) {
  4359. caps->len = (size_t) (&s.ptr[j] - caps->ptr); // Finalize current cap
  4360. caps++, caps->len = 0, caps->ptr = NULL; // Init next cap
  4361. }
  4362. i++, j++;
  4363. } else if (i < p.len && (p.ptr[i] == '*' || p.ptr[i] == '#')) {
  4364. if (caps && !caps->ptr) caps->len = 0, caps->ptr = &s.ptr[j]; // Init cap
  4365. ni = i++, nj = j + 1;
  4366. } else if (nj > 0 && nj <= s.len && (p.ptr[ni] == '#' || s.ptr[j] != '/')) {
  4367. i = ni, j = nj;
  4368. if (caps && caps->ptr == NULL && caps->len == 0) {
  4369. caps--, caps->len = 0; // Restart previous cap
  4370. }
  4371. } else {
  4372. return false;
  4373. }
  4374. }
  4375. if (caps && caps->ptr && caps->len == 0) {
  4376. caps->len = (size_t) (&s.ptr[j] - caps->ptr);
  4377. }
  4378. return true;
  4379. }
  4380. bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
  4381. return mg_match(mg_str_n(s2, n2), mg_str_n(s1, n1), NULL);
  4382. }
  4383. static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
  4384. size_t *klen, size_t *voff, size_t *vlen, char delim) {
  4385. size_t kvlen, kl;
  4386. for (kvlen = 0; ofs + kvlen < n && s[ofs + kvlen] != delim;) kvlen++;
  4387. for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
  4388. if (koff != NULL) *koff = ofs;
  4389. if (klen != NULL) *klen = kl;
  4390. if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
  4391. if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
  4392. ofs += kvlen + 1;
  4393. return ofs > n ? n : ofs;
  4394. }
  4395. bool mg_split(struct mg_str *s, struct mg_str *k, struct mg_str *v, char sep) {
  4396. size_t koff = 0, klen = 0, voff = 0, vlen = 0, off = 0;
  4397. if (s->ptr == NULL || s->len == 0) return 0;
  4398. off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen, sep);
  4399. if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
  4400. if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
  4401. *s = mg_str_n(s->ptr + off, s->len - off);
  4402. return off > 0;
  4403. }
  4404. bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
  4405. return mg_split(s, k, v, ',');
  4406. }
  4407. char *mg_hex(const void *buf, size_t len, char *to) {
  4408. const unsigned char *p = (const unsigned char *) buf;
  4409. const char *hex = "0123456789abcdef";
  4410. size_t i = 0;
  4411. for (; len--; p++) {
  4412. to[i++] = hex[p[0] >> 4];
  4413. to[i++] = hex[p[0] & 0x0f];
  4414. }
  4415. to[i] = '\0';
  4416. return to;
  4417. }
  4418. static unsigned char mg_unhex_nimble(unsigned char c) {
  4419. return (c >= '0' && c <= '9') ? (unsigned char) (c - '0')
  4420. : (c >= 'A' && c <= 'F') ? (unsigned char) (c - '7')
  4421. : (unsigned char) (c - 'W');
  4422. }
  4423. unsigned long mg_unhexn(const char *s, size_t len) {
  4424. unsigned long i = 0, v = 0;
  4425. for (i = 0; i < len; i++) v <<= 4, v |= mg_unhex_nimble(((uint8_t *) s)[i]);
  4426. return v;
  4427. }
  4428. void mg_unhex(const char *buf, size_t len, unsigned char *to) {
  4429. size_t i;
  4430. for (i = 0; i < len; i += 2) {
  4431. to[i >> 1] = (unsigned char) mg_unhexn(&buf[i], 2);
  4432. }
  4433. }
  4434. uint64_t mg_tou64(struct mg_str str) {
  4435. uint64_t result = 0;
  4436. size_t i = 0;
  4437. while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
  4438. while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
  4439. result *= 10;
  4440. result += (unsigned) (str.ptr[i] - '0');
  4441. i++;
  4442. }
  4443. return result;
  4444. }
  4445. int64_t mg_to64(struct mg_str str) {
  4446. int64_t result = 0, neg = 1, max = 922337203685477570 /* INT64_MAX/10-10 */;
  4447. size_t i = 0;
  4448. while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
  4449. if (i < str.len && str.ptr[i] == '-') neg = -1, i++;
  4450. while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
  4451. if (result > max) return 0;
  4452. result *= 10;
  4453. result += (str.ptr[i] - '0');
  4454. i++;
  4455. }
  4456. return result * neg;
  4457. }
  4458. char *mg_remove_double_dots(char *s) {
  4459. char *saved = s, *p = s;
  4460. while (*s != '\0') {
  4461. *p++ = *s++;
  4462. if (s[-1] == '/' || s[-1] == '\\') {
  4463. while (s[0] != '\0') {
  4464. if (s[0] == '/' || s[0] == '\\') {
  4465. s++;
  4466. } else if (s[0] == '.' && s[1] == '.' &&
  4467. (s[2] == '/' || s[2] == '\\')) {
  4468. s += 2;
  4469. } else {
  4470. break;
  4471. }
  4472. }
  4473. }
  4474. }
  4475. *p = '\0';
  4476. return saved;
  4477. }
  4478. #ifdef MG_ENABLE_LINES
  4479. #line 1 "src/timer.c"
  4480. #endif
  4481. #define MG_TIMER_CALLED 4
  4482. void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
  4483. unsigned flags, void (*fn)(void *), void *arg) {
  4484. struct mg_timer tmp = {0U, ms, 0U, 0U, flags, fn, arg, *head};
  4485. *t = tmp;
  4486. *head = t;
  4487. }
  4488. void mg_timer_free(struct mg_timer **head, struct mg_timer *t) {
  4489. while (*head && *head != t) head = &(*head)->next;
  4490. if (*head) *head = t->next;
  4491. }
  4492. void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
  4493. // If time goes back (wrapped around), reset timers
  4494. struct mg_timer *t, *tmp;
  4495. for (t = *head; t != NULL; t = tmp) {
  4496. tmp = t->next;
  4497. if (t->prev_ms > now_ms) t->expire = 0; // Handle time wrap
  4498. t->prev_ms = now_ms;
  4499. if (t->expire == 0 && (t->flags & MG_TIMER_RUN_NOW) &&
  4500. !(t->flags & MG_TIMER_CALLED)) {
  4501. // Handle MG_TIMER_NOW only once
  4502. } else if (t->expire == 0) {
  4503. t->expire = now_ms + t->period_ms;
  4504. }
  4505. if (t->expire > now_ms) continue;
  4506. if ((t->flags & MG_TIMER_REPEAT) || !(t->flags & MG_TIMER_CALLED)) {
  4507. t->fn(t->arg);
  4508. }
  4509. t->flags |= MG_TIMER_CALLED;
  4510. // Try to tick timers with the given period as accurate as possible,
  4511. // even if this polling function is called with some random period.
  4512. t->expire = now_ms - t->expire > t->period_ms ? now_ms + t->period_ms
  4513. : t->expire + t->period_ms;
  4514. }
  4515. }
  4516. #ifdef MG_ENABLE_LINES
  4517. #line 1 "src/tls_dummy.c"
  4518. #endif
  4519. #if !MG_ENABLE_MBEDTLS && !MG_ENABLE_OPENSSL && !MG_ENABLE_CUSTOM_TLS
  4520. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  4521. (void) opts;
  4522. mg_error(c, "TLS is not enabled");
  4523. }
  4524. void mg_tls_handshake(struct mg_connection *c) {
  4525. (void) c;
  4526. }
  4527. void mg_tls_free(struct mg_connection *c) {
  4528. (void) c;
  4529. }
  4530. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  4531. return c == NULL || buf == NULL || len == 0 ? 0 : -1;
  4532. }
  4533. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  4534. return c == NULL || buf == NULL || len == 0 ? 0 : -1;
  4535. }
  4536. size_t mg_tls_pending(struct mg_connection *c) {
  4537. (void) c;
  4538. return 0;
  4539. }
  4540. #endif
  4541. #ifdef MG_ENABLE_LINES
  4542. #line 1 "src/tls_mbed.c"
  4543. #endif
  4544. #if MG_ENABLE_MBEDTLS
  4545. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
  4546. #define MGRNG , rng_get, NULL
  4547. #else
  4548. #define MGRNG
  4549. #endif
  4550. void mg_tls_free(struct mg_connection *c) {
  4551. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4552. if (tls != NULL) {
  4553. free(tls->cafile);
  4554. mbedtls_ssl_free(&tls->ssl);
  4555. mbedtls_pk_free(&tls->pk);
  4556. mbedtls_x509_crt_free(&tls->ca);
  4557. mbedtls_x509_crt_free(&tls->cert);
  4558. mbedtls_ssl_config_free(&tls->conf);
  4559. free(tls);
  4560. c->tls = NULL;
  4561. }
  4562. }
  4563. bool mg_sock_would_block(void);
  4564. bool mg_sock_conn_reset(void);
  4565. static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
  4566. struct mg_connection *c = (struct mg_connection *) ctx;
  4567. int fd = (int) (size_t) c->fd;
  4568. int n = (int) send(fd, buf, len, 0);
  4569. MG_VERBOSE(("%lu n=%d, errno=%d", c->id, n, errno));
  4570. if (n < 0) {
  4571. if (mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_WRITE;
  4572. if (mg_sock_conn_reset()) return MBEDTLS_ERR_NET_CONN_RESET;
  4573. return MBEDTLS_ERR_NET_SEND_FAILED;
  4574. }
  4575. return n;
  4576. }
  4577. static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) {
  4578. struct mg_connection *c = (struct mg_connection *) ctx;
  4579. int n, fd = (int) (size_t) c->fd;
  4580. n = (int) recv(fd, buf, len, 0);
  4581. MG_VERBOSE(("%lu n=%d, errno=%d", c->id, n, errno));
  4582. if (n < 0) {
  4583. if (mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_READ;
  4584. if (mg_sock_conn_reset()) return MBEDTLS_ERR_NET_CONN_RESET;
  4585. return MBEDTLS_ERR_NET_RECV_FAILED;
  4586. }
  4587. return n;
  4588. }
  4589. void mg_tls_handshake(struct mg_connection *c) {
  4590. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4591. int rc;
  4592. mbedtls_ssl_set_bio(&tls->ssl, c, mg_net_send, mg_net_recv, 0);
  4593. rc = mbedtls_ssl_handshake(&tls->ssl);
  4594. if (rc == 0) { // Success
  4595. MG_DEBUG(("%lu success", c->id));
  4596. c->is_tls_hs = 0;
  4597. } else if (rc == MBEDTLS_ERR_SSL_WANT_READ ||
  4598. rc == MBEDTLS_ERR_SSL_WANT_WRITE) { // Still pending
  4599. MG_VERBOSE(("%lu pending, %d%d %d (-%#x)", c->id, c->is_connecting,
  4600. c->is_tls_hs, rc, -rc));
  4601. } else {
  4602. mg_error(c, "TLS handshake: -%#x", -rc); // Error
  4603. }
  4604. }
  4605. static int mbed_rng(void *ctx, unsigned char *buf, size_t len) {
  4606. mg_random(buf, len);
  4607. (void) ctx;
  4608. return 0;
  4609. }
  4610. static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) {
  4611. n = (int) strlen(s2) - 1;
  4612. MG_VERBOSE(("%lu %d %.*s", ((struct mg_connection *) c)->id, lev, n, s2));
  4613. (void) s;
  4614. }
  4615. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
  4616. static int rng_get(void *p_rng, unsigned char *buf, size_t len) {
  4617. (void) p_rng;
  4618. mg_random(buf, len);
  4619. return 0;
  4620. }
  4621. #endif
  4622. static struct mg_str mg_loadfile(struct mg_fs *fs, const char *path) {
  4623. size_t n = 0;
  4624. if (path[0] == '-') return mg_str(path);
  4625. char *p = mg_file_read(fs, path, &n);
  4626. return mg_str_n(p, n);
  4627. }
  4628. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  4629. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  4630. struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
  4631. int rc = 0;
  4632. c->tls = tls;
  4633. if (c->tls == NULL) {
  4634. mg_error(c, "TLS OOM");
  4635. goto fail;
  4636. }
  4637. MG_DEBUG(("%lu Setting TLS", c->id));
  4638. mbedtls_ssl_init(&tls->ssl);
  4639. mbedtls_ssl_config_init(&tls->conf);
  4640. mbedtls_x509_crt_init(&tls->ca);
  4641. mbedtls_x509_crt_init(&tls->cert);
  4642. mbedtls_pk_init(&tls->pk);
  4643. mbedtls_ssl_conf_dbg(&tls->conf, debug_cb, c);
  4644. #if defined(MG_MBEDTLS_DEBUG_LEVEL)
  4645. mbedtls_debug_set_threshold(MG_MBEDTLS_DEBUG_LEVEL);
  4646. #endif
  4647. if ((rc = mbedtls_ssl_config_defaults(
  4648. &tls->conf,
  4649. c->is_client ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
  4650. MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
  4651. mg_error(c, "tls defaults %#x", -rc);
  4652. goto fail;
  4653. }
  4654. mbedtls_ssl_conf_rng(&tls->conf, mbed_rng, c);
  4655. if (opts->ca == NULL || strcmp(opts->ca, "*") == 0) {
  4656. mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
  4657. } else if (opts->ca != NULL && opts->ca[0] != '\0') {
  4658. #if defined(MBEDTLS_X509_CA_CHAIN_ON_DISK)
  4659. tls->cafile = strdup(opts->ca);
  4660. rc = mbedtls_ssl_conf_ca_chain_file(&tls->conf, tls->cafile, NULL);
  4661. if (rc != 0) {
  4662. mg_error(c, "parse on-disk chain(%s) err %#x", tls->cafile, -rc);
  4663. goto fail;
  4664. }
  4665. #else
  4666. struct mg_str s = mg_loadfile(fs, opts->ca);
  4667. rc = mbedtls_x509_crt_parse(&tls->ca, (uint8_t *) s.ptr, s.len + 1);
  4668. if (opts->ca[0] != '-') free((char *) s.ptr);
  4669. if (rc != 0) {
  4670. mg_error(c, "parse(%s) err %#x", opts->ca, -rc);
  4671. goto fail;
  4672. }
  4673. mbedtls_ssl_conf_ca_chain(&tls->conf, &tls->ca, NULL);
  4674. #endif
  4675. if (opts->srvname.len > 0) {
  4676. char *x = mg_mprintf("%.*s", (int) opts->srvname.len, opts->srvname.ptr);
  4677. mbedtls_ssl_set_hostname(&tls->ssl, x);
  4678. free(x);
  4679. }
  4680. mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
  4681. }
  4682. if (opts->cert != NULL && opts->cert[0] != '\0') {
  4683. struct mg_str s = mg_loadfile(fs, opts->cert);
  4684. const char *key = opts->certkey == NULL ? opts->cert : opts->certkey;
  4685. rc = mbedtls_x509_crt_parse(&tls->cert, (uint8_t *) s.ptr, s.len + 1);
  4686. if (opts->cert[0] != '-') free((char *) s.ptr);
  4687. if (rc != 0) {
  4688. mg_error(c, "parse(%s) err %#x", opts->cert, -rc);
  4689. goto fail;
  4690. }
  4691. s = mg_loadfile(fs, key);
  4692. rc = mbedtls_pk_parse_key(&tls->pk, (uint8_t *) s.ptr, s.len + 1, NULL,
  4693. 0 MGRNG);
  4694. if (key[0] != '-') free((char *) s.ptr);
  4695. if (rc != 0) {
  4696. mg_error(c, "tls key(%s) %#x", key, -rc);
  4697. goto fail;
  4698. }
  4699. rc = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->cert, &tls->pk);
  4700. if (rc != 0) {
  4701. mg_error(c, "own cert %#x", -rc);
  4702. goto fail;
  4703. }
  4704. }
  4705. if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) {
  4706. mg_error(c, "setup err %#x", -rc);
  4707. goto fail;
  4708. }
  4709. c->tls = tls;
  4710. c->is_tls = 1;
  4711. c->is_tls_hs = 1;
  4712. if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
  4713. mg_tls_handshake(c);
  4714. }
  4715. return;
  4716. fail:
  4717. mg_tls_free(c);
  4718. }
  4719. size_t mg_tls_pending(struct mg_connection *c) {
  4720. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4721. return tls == NULL ? 0 : mbedtls_ssl_get_bytes_avail(&tls->ssl);
  4722. }
  4723. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  4724. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4725. long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
  4726. return n == 0 ? -1 : n == MBEDTLS_ERR_SSL_WANT_READ ? 0 : n;
  4727. }
  4728. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  4729. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4730. long n = mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len);
  4731. return n == 0 ? -1 : n == MBEDTLS_ERR_SSL_WANT_WRITE ? 0 : n;
  4732. }
  4733. #endif
  4734. #ifdef MG_ENABLE_LINES
  4735. #line 1 "src/tls_openssl.c"
  4736. #endif
  4737. #if MG_ENABLE_OPENSSL
  4738. static int mg_tls_err(struct mg_tls *tls, int res) {
  4739. int err = SSL_get_error(tls->ssl, res);
  4740. // We've just fetched the last error from the queue.
  4741. // Now we need to clear the error queue. If we do not, then the following
  4742. // can happen (actually reported):
  4743. // - A new connection is accept()-ed with cert error (e.g. self-signed cert)
  4744. // - Since all accept()-ed connections share listener's context,
  4745. // - *ALL* SSL accepted connection report read error on the next poll cycle.
  4746. // Thus a single errored connection can close all the rest, unrelated ones.
  4747. // Clearing the error keeps the shared SSL_CTX in an OK state.
  4748. if (err != 0) ERR_print_errors_fp(stderr);
  4749. ERR_clear_error();
  4750. if (err == SSL_ERROR_WANT_READ) return 0;
  4751. if (err == SSL_ERROR_WANT_WRITE) return 0;
  4752. return err;
  4753. }
  4754. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  4755. struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
  4756. const char *id = "mongoose";
  4757. static unsigned char s_initialised = 0;
  4758. int rc;
  4759. if (tls == NULL) {
  4760. mg_error(c, "TLS OOM");
  4761. goto fail;
  4762. }
  4763. if (!s_initialised) {
  4764. SSL_library_init();
  4765. s_initialised++;
  4766. }
  4767. MG_DEBUG(("%lu Setting TLS, CA: %s, cert: %s, key: %s", c->id,
  4768. opts->ca == NULL ? "null" : opts->ca,
  4769. opts->cert == NULL ? "null" : opts->cert,
  4770. opts->certkey == NULL ? "null" : opts->certkey));
  4771. tls->ctx = c->is_client ? SSL_CTX_new(SSLv23_client_method())
  4772. : SSL_CTX_new(SSLv23_server_method());
  4773. if ((tls->ssl = SSL_new(tls->ctx)) == NULL) {
  4774. mg_error(c, "SSL_new");
  4775. goto fail;
  4776. }
  4777. SSL_set_session_id_context(tls->ssl, (const uint8_t *) id,
  4778. (unsigned) strlen(id));
  4779. // Disable deprecated protocols
  4780. SSL_set_options(tls->ssl, SSL_OP_NO_SSLv2);
  4781. SSL_set_options(tls->ssl, SSL_OP_NO_SSLv3);
  4782. SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1);
  4783. SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1_1);
  4784. #ifdef MG_ENABLE_OPENSSL_NO_COMPRESSION
  4785. SSL_set_options(tls->ssl, SSL_OP_NO_COMPRESSION);
  4786. #endif
  4787. #ifdef MG_ENABLE_OPENSSL_CIPHER_SERVER_PREFERENCE
  4788. SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
  4789. #endif
  4790. if (opts->ca != NULL && opts->ca[0] != '\0') {
  4791. SSL_set_verify(tls->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
  4792. NULL);
  4793. if ((rc = SSL_CTX_load_verify_locations(tls->ctx, opts->ca, NULL)) != 1) {
  4794. mg_error(c, "load('%s') %d err %d", opts->ca, rc, mg_tls_err(tls, rc));
  4795. goto fail;
  4796. }
  4797. }
  4798. if (opts->cert != NULL && opts->cert[0] != '\0') {
  4799. const char *key = opts->certkey;
  4800. if (key == NULL) key = opts->cert;
  4801. if ((rc = SSL_use_certificate_file(tls->ssl, opts->cert, 1)) != 1) {
  4802. mg_error(c, "Invalid SSL cert, err %d", mg_tls_err(tls, rc));
  4803. goto fail;
  4804. } else if ((rc = SSL_use_PrivateKey_file(tls->ssl, key, 1)) != 1) {
  4805. mg_error(c, "Invalid SSL key, err %d", mg_tls_err(tls, rc));
  4806. goto fail;
  4807. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4808. } else if ((rc = SSL_use_certificate_chain_file(tls->ssl, opts->cert)) !=
  4809. 1) {
  4810. mg_error(c, "Invalid chain, err %d", mg_tls_err(tls, rc));
  4811. goto fail;
  4812. #endif
  4813. } else {
  4814. SSL_set_mode(tls->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  4815. #if OPENSSL_VERSION_NUMBER > 0x10002000L
  4816. SSL_set_ecdh_auto(tls->ssl, 1);
  4817. #endif
  4818. }
  4819. }
  4820. if (opts->ciphers != NULL) SSL_set_cipher_list(tls->ssl, opts->ciphers);
  4821. if (opts->srvname.len > 0) {
  4822. char *s = mg_mprintf("%.*s", (int) opts->srvname.len, opts->srvname.ptr);
  4823. SSL_set1_host(tls->ssl, s);
  4824. free(s);
  4825. }
  4826. c->tls = tls;
  4827. c->is_tls = 1;
  4828. c->is_tls_hs = 1;
  4829. if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
  4830. mg_tls_handshake(c);
  4831. }
  4832. MG_DEBUG(("%lu SSL %s OK", c->id, c->is_accepted ? "accept" : "client"));
  4833. return;
  4834. fail:
  4835. c->is_closing = 1;
  4836. free(tls);
  4837. }
  4838. void mg_tls_handshake(struct mg_connection *c) {
  4839. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4840. int rc;
  4841. SSL_set_fd(tls->ssl, (int) (size_t) c->fd);
  4842. rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl);
  4843. if (rc == 1) {
  4844. MG_DEBUG(("%lu success", c->id));
  4845. c->is_tls_hs = 0;
  4846. } else {
  4847. int code = mg_tls_err(tls, rc);
  4848. if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
  4849. }
  4850. }
  4851. void mg_tls_free(struct mg_connection *c) {
  4852. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4853. if (tls == NULL) return;
  4854. SSL_free(tls->ssl);
  4855. SSL_CTX_free(tls->ctx);
  4856. free(tls);
  4857. c->tls = NULL;
  4858. }
  4859. size_t mg_tls_pending(struct mg_connection *c) {
  4860. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4861. return tls == NULL ? 0 : (size_t) SSL_pending(tls->ssl);
  4862. }
  4863. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  4864. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4865. int n = SSL_read(tls->ssl, buf, (int) len);
  4866. return n == 0 ? -1 : n < 0 && mg_tls_err(tls, n) == 0 ? 0 : n;
  4867. }
  4868. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  4869. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4870. int n = SSL_write(tls->ssl, buf, (int) len);
  4871. return n == 0 ? -1 : n < 0 && mg_tls_err(tls, n) == 0 ? 0 : n;
  4872. }
  4873. #endif
  4874. #ifdef MG_ENABLE_LINES
  4875. #line 1 "src/url.c"
  4876. #endif
  4877. struct url {
  4878. size_t key, user, pass, host, port, uri, end;
  4879. };
  4880. int mg_url_is_ssl(const char *url) {
  4881. return strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0 ||
  4882. strncmp(url, "mqtts:", 6) == 0 || strncmp(url, "ssl:", 4) == 0 ||
  4883. strncmp(url, "tls:", 4) == 0;
  4884. }
  4885. static struct url urlparse(const char *url) {
  4886. size_t i;
  4887. struct url u;
  4888. memset(&u, 0, sizeof(u));
  4889. for (i = 0; url[i] != '\0'; i++) {
  4890. if (url[i] == '/' && i > 0 && u.host == 0 && url[i - 1] == '/') {
  4891. u.host = i + 1;
  4892. u.port = 0;
  4893. } else if (url[i] == ']') {
  4894. u.port = 0; // IPv6 URLs, like http://[::1]/bar
  4895. } else if (url[i] == ':' && u.port == 0 && u.uri == 0) {
  4896. u.port = i + 1;
  4897. } else if (url[i] == '@' && u.user == 0 && u.pass == 0 && u.uri == 0) {
  4898. u.user = u.host;
  4899. u.pass = u.port;
  4900. u.host = i + 1;
  4901. u.port = 0;
  4902. } else if (url[i] == '/' && u.host && u.uri == 0) {
  4903. u.uri = i;
  4904. }
  4905. }
  4906. u.end = i;
  4907. #if 0
  4908. printf("[%s] %d %d %d %d %d\n", url, u.user, u.pass, u.host, u.port, u.uri);
  4909. #endif
  4910. return u;
  4911. }
  4912. struct mg_str mg_url_host(const char *url) {
  4913. struct url u = urlparse(url);
  4914. size_t n = u.port ? u.port - u.host - 1
  4915. : u.uri ? u.uri - u.host
  4916. : u.end - u.host;
  4917. struct mg_str s = mg_str_n(url + u.host, n);
  4918. return s;
  4919. }
  4920. const char *mg_url_uri(const char *url) {
  4921. struct url u = urlparse(url);
  4922. return u.uri ? url + u.uri : "/";
  4923. }
  4924. unsigned short mg_url_port(const char *url) {
  4925. struct url u = urlparse(url);
  4926. unsigned short port = 0;
  4927. if (strncmp(url, "http:", 5) == 0 || strncmp(url, "ws:", 3) == 0) port = 80;
  4928. if (strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0)
  4929. port = 443;
  4930. if (strncmp(url, "mqtt:", 5) == 0) port = 1883;
  4931. if (strncmp(url, "mqtts:", 6) == 0) port = 8883;
  4932. if (u.port) port = (unsigned short) atoi(url + u.port);
  4933. return port;
  4934. }
  4935. struct mg_str mg_url_user(const char *url) {
  4936. struct url u = urlparse(url);
  4937. struct mg_str s = mg_str("");
  4938. if (u.user && (u.pass || u.host)) {
  4939. size_t n = u.pass ? u.pass - u.user - 1 : u.host - u.user - 1;
  4940. s = mg_str_n(url + u.user, n);
  4941. }
  4942. return s;
  4943. }
  4944. struct mg_str mg_url_pass(const char *url) {
  4945. struct url u = urlparse(url);
  4946. struct mg_str s = mg_str_n("", 0UL);
  4947. if (u.pass && u.host) {
  4948. size_t n = u.host - u.pass - 1;
  4949. s = mg_str_n(url + u.pass, n);
  4950. }
  4951. return s;
  4952. }
  4953. #ifdef MG_ENABLE_LINES
  4954. #line 1 "src/util.c"
  4955. #endif
  4956. #if MG_ENABLE_CUSTOM_RANDOM
  4957. #else
  4958. void mg_random(void *buf, size_t len) {
  4959. bool done = false;
  4960. unsigned char *p = (unsigned char *) buf;
  4961. #if MG_ARCH == MG_ARCH_ESP32
  4962. while (len--) *p++ = (unsigned char) (esp_random() & 255);
  4963. done = true;
  4964. #elif MG_ARCH == MG_ARCH_WIN32
  4965. #elif MG_ARCH == MG_ARCH_UNIX
  4966. FILE *fp = fopen("/dev/urandom", "rb");
  4967. if (fp != NULL) {
  4968. if (fread(buf, 1, len, fp) == len) done = true;
  4969. fclose(fp);
  4970. }
  4971. #endif
  4972. // If everything above did not work, fallback to a pseudo random generator
  4973. while (!done && len--) *p++ = (unsigned char) (rand() & 255);
  4974. }
  4975. #endif
  4976. char *mg_random_str(char *buf, size_t len) {
  4977. size_t i;
  4978. mg_random(buf, len);
  4979. for (i = 0; i < len; i++) {
  4980. uint8_t c = ((uint8_t *) buf)[i] % 62U;
  4981. buf[i] = i == len - 1 ? (char) '\0' // 0-terminate last byte
  4982. : c < 26 ? (char) ('a' + c) // lowercase
  4983. : c < 52 ? (char) ('A' + c - 26) // uppercase
  4984. : (char) ('0' + c - 52); // numeric
  4985. }
  4986. return buf;
  4987. }
  4988. uint32_t mg_ntohl(uint32_t net) {
  4989. uint8_t data[4] = {0, 0, 0, 0};
  4990. memcpy(&data, &net, sizeof(data));
  4991. return (((uint32_t) data[3]) << 0) | (((uint32_t) data[2]) << 8) |
  4992. (((uint32_t) data[1]) << 16) | (((uint32_t) data[0]) << 24);
  4993. }
  4994. uint16_t mg_ntohs(uint16_t net) {
  4995. uint8_t data[2] = {0, 0};
  4996. memcpy(&data, &net, sizeof(data));
  4997. return (uint16_t) ((uint16_t) data[1] | (((uint16_t) data[0]) << 8));
  4998. }
  4999. uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len) {
  5000. int i;
  5001. crc = ~crc;
  5002. while (len--) {
  5003. crc ^= *(unsigned char *) buf++;
  5004. for (i = 0; i < 8; i++) crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
  5005. }
  5006. return ~crc;
  5007. }
  5008. static int isbyte(int n) {
  5009. return n >= 0 && n <= 255;
  5010. }
  5011. static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
  5012. int n, a, b, c, d, slash = 32, len = 0;
  5013. if ((sscanf(spec, "%d.%d.%d.%d/%d%n", &a, &b, &c, &d, &slash, &n) == 5 ||
  5014. sscanf(spec, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4) &&
  5015. isbyte(a) && isbyte(b) && isbyte(c) && isbyte(d) && slash >= 0 &&
  5016. slash < 33) {
  5017. len = n;
  5018. *net = ((uint32_t) a << 24) | ((uint32_t) b << 16) | ((uint32_t) c << 8) |
  5019. (uint32_t) d;
  5020. *mask = slash ? (uint32_t) (0xffffffffU << (32 - slash)) : (uint32_t) 0;
  5021. }
  5022. return len;
  5023. }
  5024. int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip) {
  5025. struct mg_str k, v;
  5026. int allowed = acl.len == 0 ? '+' : '-'; // If any ACL is set, deny by default
  5027. while (mg_commalist(&acl, &k, &v)) {
  5028. uint32_t net, mask;
  5029. if (k.ptr[0] != '+' && k.ptr[0] != '-') return -1;
  5030. if (parse_net(&k.ptr[1], &net, &mask) == 0) return -2;
  5031. if ((mg_ntohl(remote_ip) & mask) == net) allowed = k.ptr[0];
  5032. }
  5033. return allowed == '+';
  5034. }
  5035. #if MG_ENABLE_CUSTOM_MILLIS
  5036. #else
  5037. uint64_t mg_millis(void) {
  5038. #if MG_ARCH == MG_ARCH_WIN32
  5039. return GetTickCount();
  5040. #elif MG_ARCH == MG_ARCH_RP2040
  5041. return time_us_64() / 1000;
  5042. #elif MG_ARCH == MG_ARCH_ESP32
  5043. return esp_timer_get_time() / 1000;
  5044. #elif MG_ARCH == MG_ARCH_ESP8266
  5045. return xTaskGetTickCount() * portTICK_PERIOD_MS;
  5046. #elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP
  5047. return xTaskGetTickCount() * portTICK_PERIOD_MS;
  5048. #elif MG_ARCH == MG_ARCH_AZURERTOS
  5049. return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND);
  5050. #elif MG_ARCH == MG_ARCH_UNIX && defined(__APPLE__)
  5051. // Apple CLOCK_MONOTONIC_RAW is equivalent to CLOCK_BOOTTIME on linux
  5052. // Apple CLOCK_UPTIME_RAW is equivalent to CLOCK_MONOTONIC_RAW on linux
  5053. return clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1000000;
  5054. #elif MG_ARCH == MG_ARCH_UNIX
  5055. struct timespec ts = {0, 0};
  5056. // See #1615 - prefer monotonic clock
  5057. #if defined(CLOCK_MONOTONIC_RAW)
  5058. // Raw hardware-based time that is not subject to NTP adjustment
  5059. clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
  5060. #elif defined(CLOCK_MONOTONIC)
  5061. // Affected by the incremental adjustments performed by adjtime and NTP
  5062. clock_gettime(CLOCK_MONOTONIC, &ts);
  5063. #else
  5064. // Affected by discontinuous jumps in the system time and by the incremental
  5065. // adjustments performed by adjtime and NTP
  5066. clock_gettime(CLOCK_REALTIME, &ts);
  5067. #endif
  5068. return ((uint64_t) ts.tv_sec * 1000 + (uint64_t) ts.tv_nsec / 1000000);
  5069. #elif defined(ARDUINO)
  5070. return (uint64_t) millis();
  5071. #else
  5072. return (uint64_t) (time(NULL) * 1000);
  5073. #endif
  5074. }
  5075. #endif
  5076. #ifdef MG_ENABLE_LINES
  5077. #line 1 "src/ws.c"
  5078. #endif
  5079. struct ws_msg {
  5080. uint8_t flags;
  5081. size_t header_len;
  5082. size_t data_len;
  5083. };
  5084. size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
  5085. va_list *ap) {
  5086. size_t len = c->send.len;
  5087. size_t n = mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  5088. mg_ws_wrap(c, c->send.len - len, op);
  5089. return n;
  5090. }
  5091. size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...) {
  5092. size_t len = 0;
  5093. va_list ap;
  5094. va_start(ap, fmt);
  5095. len = mg_ws_vprintf(c, op, fmt, &ap);
  5096. va_end(ap);
  5097. return len;
  5098. }
  5099. static void ws_handshake(struct mg_connection *c, const struct mg_str *wskey,
  5100. const struct mg_str *wsproto, const char *fmt,
  5101. va_list *ap) {
  5102. const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
  5103. unsigned char sha[20], b64_sha[30];
  5104. mg_sha1_ctx sha_ctx;
  5105. mg_sha1_init(&sha_ctx);
  5106. mg_sha1_update(&sha_ctx, (unsigned char *) wskey->ptr, wskey->len);
  5107. mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
  5108. mg_sha1_final(sha, &sha_ctx);
  5109. mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
  5110. mg_xprintf(mg_pfn_iobuf, &c->send,
  5111. "HTTP/1.1 101 Switching Protocols\r\n"
  5112. "Upgrade: websocket\r\n"
  5113. "Connection: Upgrade\r\n"
  5114. "Sec-WebSocket-Accept: %s\r\n",
  5115. b64_sha);
  5116. if (fmt != NULL) mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  5117. if (wsproto != NULL) {
  5118. mg_printf(c, "Sec-WebSocket-Protocol: %.*s\r\n", (int) wsproto->len,
  5119. wsproto->ptr);
  5120. }
  5121. mg_send(c, "\r\n", 2);
  5122. }
  5123. static uint32_t be32(const uint8_t *p) {
  5124. return (((uint32_t) p[3]) << 0) | (((uint32_t) p[2]) << 8) |
  5125. (((uint32_t) p[1]) << 16) | (((uint32_t) p[0]) << 24);
  5126. }
  5127. static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
  5128. size_t i, n = 0, mask_len = 0;
  5129. memset(msg, 0, sizeof(*msg));
  5130. if (len >= 2) {
  5131. n = buf[1] & 0x7f; // Frame length
  5132. mask_len = buf[1] & 128 ? 4 : 0; // last bit is a mask bit
  5133. msg->flags = buf[0];
  5134. if (n < 126 && len >= mask_len) {
  5135. msg->data_len = n;
  5136. msg->header_len = 2 + mask_len;
  5137. } else if (n == 126 && len >= 4 + mask_len) {
  5138. msg->header_len = 4 + mask_len;
  5139. msg->data_len = (((size_t) buf[2]) << 8) | buf[3];
  5140. } else if (len >= 10 + mask_len) {
  5141. msg->header_len = 10 + mask_len;
  5142. msg->data_len =
  5143. (size_t) (((uint64_t) be32(buf + 2) << 32) + be32(buf + 6));
  5144. }
  5145. }
  5146. // Sanity check, and integer overflow protection for the boundary check below
  5147. // data_len should not be larger than 1 Gb
  5148. if (msg->data_len > 1024 * 1024 * 1024) return 0;
  5149. if (msg->header_len + msg->data_len > len) return 0;
  5150. if (mask_len > 0) {
  5151. uint8_t *p = buf + msg->header_len, *m = p - mask_len;
  5152. for (i = 0; i < msg->data_len; i++) p[i] ^= m[i & 3];
  5153. }
  5154. return msg->header_len + msg->data_len;
  5155. }
  5156. static size_t mkhdr(size_t len, int op, bool is_client, uint8_t *buf) {
  5157. size_t n = 0;
  5158. buf[0] = (uint8_t) (op | 128);
  5159. if (len < 126) {
  5160. buf[1] = (unsigned char) len;
  5161. n = 2;
  5162. } else if (len < 65536) {
  5163. uint16_t tmp = mg_htons((uint16_t) len);
  5164. buf[1] = 126;
  5165. memcpy(&buf[2], &tmp, sizeof(tmp));
  5166. n = 4;
  5167. } else {
  5168. uint32_t tmp;
  5169. buf[1] = 127;
  5170. tmp = mg_htonl((uint32_t) (((uint64_t) len) >> 32));
  5171. memcpy(&buf[2], &tmp, sizeof(tmp));
  5172. tmp = mg_htonl((uint32_t) (len & 0xffffffffU));
  5173. memcpy(&buf[6], &tmp, sizeof(tmp));
  5174. n = 10;
  5175. }
  5176. if (is_client) {
  5177. buf[1] |= 1 << 7; // Set masking flag
  5178. mg_random(&buf[n], 4);
  5179. n += 4;
  5180. }
  5181. return n;
  5182. }
  5183. static void mg_ws_mask(struct mg_connection *c, size_t len) {
  5184. if (c->is_client && c->send.buf != NULL) {
  5185. size_t i;
  5186. uint8_t *p = c->send.buf + c->send.len - len, *mask = p - 4;
  5187. for (i = 0; i < len; i++) p[i] ^= mask[i & 3];
  5188. }
  5189. }
  5190. size_t mg_ws_send(struct mg_connection *c, const void *buf, size_t len,
  5191. int op) {
  5192. uint8_t header[14];
  5193. size_t header_len = mkhdr(len, op, c->is_client, header);
  5194. mg_send(c, header, header_len);
  5195. MG_VERBOSE(("WS out: %d [%.*s]", (int) len, (int) len, buf));
  5196. mg_send(c, buf, len);
  5197. mg_ws_mask(c, len);
  5198. return header_len + len;
  5199. }
  5200. static bool mg_ws_client_handshake(struct mg_connection *c) {
  5201. int n = mg_http_get_request_len(c->recv.buf, c->recv.len);
  5202. if (n < 0) {
  5203. mg_error(c, "not http"); // Some just, not an HTTP request
  5204. } else if (n > 0) {
  5205. if (n < 15 || memcmp(c->recv.buf + 9, "101", 3) != 0) {
  5206. mg_error(c, "handshake error");
  5207. } else {
  5208. struct mg_http_message hm;
  5209. mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
  5210. c->is_websocket = 1;
  5211. mg_call(c, MG_EV_WS_OPEN, &hm);
  5212. }
  5213. mg_iobuf_del(&c->recv, 0, (size_t) n);
  5214. } else {
  5215. return true; // Request is not yet received, quit event handler
  5216. }
  5217. return false; // Continue event handler
  5218. }
  5219. static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
  5220. void *fn_data) {
  5221. struct ws_msg msg;
  5222. size_t ofs = (size_t) c->pfn_data;
  5223. // assert(ofs < c->recv.len);
  5224. if (ev == MG_EV_READ) {
  5225. if (c->is_client && !c->is_websocket && mg_ws_client_handshake(c)) return;
  5226. while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) {
  5227. char *s = (char *) c->recv.buf + ofs + msg.header_len;
  5228. struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
  5229. size_t len = msg.header_len + msg.data_len;
  5230. uint8_t final = msg.flags & 128, op = msg.flags & 15;
  5231. // MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op,
  5232. // (int) m.data.len, (int) m.data.len, m.data.ptr));
  5233. switch (op) {
  5234. case WEBSOCKET_OP_CONTINUE:
  5235. mg_call(c, MG_EV_WS_CTL, &m);
  5236. break;
  5237. case WEBSOCKET_OP_PING:
  5238. MG_DEBUG(("%s", "WS PONG"));
  5239. mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG);
  5240. mg_call(c, MG_EV_WS_CTL, &m);
  5241. break;
  5242. case WEBSOCKET_OP_PONG:
  5243. mg_call(c, MG_EV_WS_CTL, &m);
  5244. break;
  5245. case WEBSOCKET_OP_TEXT:
  5246. case WEBSOCKET_OP_BINARY:
  5247. if (final) mg_call(c, MG_EV_WS_MSG, &m);
  5248. break;
  5249. case WEBSOCKET_OP_CLOSE:
  5250. MG_DEBUG(("%lu Got WS CLOSE", c->id));
  5251. mg_call(c, MG_EV_WS_CTL, &m);
  5252. mg_ws_send(c, "", 0, WEBSOCKET_OP_CLOSE);
  5253. c->is_draining = 1;
  5254. break;
  5255. default:
  5256. // Per RFC6455, close conn when an unknown op is recvd
  5257. mg_error(c, "unknown WS op %d", op);
  5258. break;
  5259. }
  5260. // Handle fragmented frames: strip header, keep in c->recv
  5261. if (final == 0 || op == 0) {
  5262. if (op) ofs++, len--, msg.header_len--; // First frame
  5263. mg_iobuf_del(&c->recv, ofs, msg.header_len); // Strip header
  5264. len -= msg.header_len;
  5265. ofs += len;
  5266. c->pfn_data = (void *) ofs;
  5267. // MG_INFO(("FRAG %d [%.*s]", (int) ofs, (int) ofs, c->recv.buf));
  5268. }
  5269. // Remove non-fragmented frame
  5270. if (final && op) mg_iobuf_del(&c->recv, ofs, len);
  5271. // Last chunk of the fragmented frame
  5272. if (final && !op) {
  5273. m.flags = c->recv.buf[0];
  5274. m.data = mg_str_n((char *) &c->recv.buf[1], (size_t) (ofs - 1));
  5275. mg_call(c, MG_EV_WS_MSG, &m);
  5276. mg_iobuf_del(&c->recv, 0, ofs);
  5277. ofs = 0;
  5278. c->pfn_data = NULL;
  5279. }
  5280. }
  5281. }
  5282. (void) fn_data;
  5283. (void) ev_data;
  5284. }
  5285. struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
  5286. mg_event_handler_t fn, void *fn_data,
  5287. const char *fmt, ...) {
  5288. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  5289. if (c != NULL) {
  5290. char nonce[16], key[30];
  5291. struct mg_str host = mg_url_host(url);
  5292. mg_random(nonce, sizeof(nonce));
  5293. mg_base64_encode((unsigned char *) nonce, sizeof(nonce), key);
  5294. mg_xprintf(mg_pfn_iobuf, &c->send,
  5295. "GET %s HTTP/1.1\r\n"
  5296. "Upgrade: websocket\r\n"
  5297. "Host: %.*s\r\n"
  5298. "Connection: Upgrade\r\n"
  5299. "Sec-WebSocket-Version: 13\r\n"
  5300. "Sec-WebSocket-Key: %s\r\n",
  5301. mg_url_uri(url), (int) host.len, host.ptr, key);
  5302. if (fmt != NULL) {
  5303. va_list ap;
  5304. va_start(ap, fmt);
  5305. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
  5306. va_end(ap);
  5307. }
  5308. mg_xprintf(mg_pfn_iobuf, &c->send, "\r\n");
  5309. c->pfn = mg_ws_cb;
  5310. c->pfn_data = NULL;
  5311. }
  5312. return c;
  5313. }
  5314. void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm,
  5315. const char *fmt, ...) {
  5316. struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
  5317. c->pfn = mg_ws_cb;
  5318. c->pfn_data = NULL;
  5319. if (wskey == NULL) {
  5320. mg_http_reply(c, 426, "", "WS upgrade expected\n");
  5321. c->is_draining = 1;
  5322. } else {
  5323. struct mg_str *wsproto = mg_http_get_header(hm, "Sec-WebSocket-Protocol");
  5324. va_list ap;
  5325. va_start(ap, fmt);
  5326. ws_handshake(c, wskey, wsproto, fmt, &ap);
  5327. va_end(ap);
  5328. c->is_websocket = 1;
  5329. c->is_resp = 0;
  5330. mg_call(c, MG_EV_WS_OPEN, hm);
  5331. }
  5332. }
  5333. size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
  5334. uint8_t header[14], *p;
  5335. size_t header_len = mkhdr(len, op, c->is_client, header);
  5336. // NOTE: order of operations is important!
  5337. mg_iobuf_add(&c->send, c->send.len, NULL, header_len);
  5338. p = &c->send.buf[c->send.len - len]; // p points to data
  5339. memmove(p, p - header_len, len); // Shift data
  5340. memcpy(p - header_len, header, header_len); // Prepend header
  5341. mg_ws_mask(c, len); // Mask data
  5342. return c->send.len;
  5343. }
  5344. #ifdef MG_ENABLE_LINES
  5345. #line 1 "mip/driver_enc28j60.c"
  5346. #endif
  5347. #if MG_ENABLE_MIP
  5348. // Instruction set
  5349. enum { OP_RCR, OP_RBM, OP_WCR, OP_WBM, OP_BFS, OP_BFC, OP_SRC };
  5350. static uint8_t rd(struct mip_spi *spi, uint8_t op, uint8_t addr) {
  5351. spi->begin(spi->spi);
  5352. spi->txn(spi->spi, (uint8_t) ((op << 5) | (addr & 0x1f)));
  5353. uint8_t value = spi->txn(spi->spi, 255);
  5354. if (addr & 0x80) value = spi->txn(spi->spi, 255);
  5355. spi->end(spi->spi);
  5356. return value;
  5357. }
  5358. static bool mip_driver_enc28j60_init(uint8_t *mac, void *data) {
  5359. (void) mac, (void) data;
  5360. rd(data, OP_SRC, 0x1f);
  5361. return false;
  5362. }
  5363. static size_t mip_driver_enc28j60_tx(const void *buf, size_t len, void *data) {
  5364. (void) buf, (void) len, (void) data;
  5365. return 0;
  5366. }
  5367. static size_t mip_driver_enc28j60_rx(void *buf, size_t len, void *data) {
  5368. (void) buf, (void) len, (void) data;
  5369. return 0;
  5370. }
  5371. static bool mip_driver_enc28j60_up(void *data) {
  5372. (void) data;
  5373. return false;
  5374. }
  5375. struct mip_driver mip_driver_enc28j60 = {.init = mip_driver_enc28j60_init,
  5376. .tx = mip_driver_enc28j60_tx,
  5377. .rx = mip_driver_enc28j60_rx,
  5378. .up = mip_driver_enc28j60_up};
  5379. #endif
  5380. #ifdef MG_ENABLE_LINES
  5381. #line 1 "mip/driver_stm32.c"
  5382. #endif
  5383. #if MG_ENABLE_MIP && defined(__arm__)
  5384. // define to your own clock if using external clocking
  5385. #if !defined(MG_STM32_CLK_HSE)
  5386. #define MG_STM32_CLK_HSE 8000000UL
  5387. #endif
  5388. // define to your chip internal clock if different
  5389. #if !defined(MG_STM32_CLK_HSI)
  5390. #define MG_STM32_CLK_HSI 16000000UL
  5391. #endif
  5392. struct stm32_eth {
  5393. volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR,
  5394. MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR,
  5395. MACIMR, MACA0HR, MACA0LR, MACA1HR, MACA1LR, MACA2HR, MACA2LR, MACA3HR,
  5396. MACA3LR, RESERVED2[40], MMCCR, MMCRIR, MMCTIR, MMCRIMR, MMCTIMR,
  5397. RESERVED3[14], MMCTGFSCCR, MMCTGFMSCCR, RESERVED4[5], MMCTGFCR,
  5398. RESERVED5[10], MMCRFCECR, MMCRFAECR, RESERVED6[10], MMCRGUFCR,
  5399. RESERVED7[334], PTPTSCR, PTPSSIR, PTPTSHR, PTPTSLR, PTPTSHUR, PTPTSLUR,
  5400. PTPTSAR, PTPTTHR, PTPTTLR, RESERVED8, PTPTSSR, PTPPPSCR, RESERVED9[564],
  5401. DMABMR, DMATPDR, DMARPDR, DMARDLAR, DMATDLAR, DMASR, DMAOMR, DMAIER,
  5402. DMAMFBOCR, DMARSWTR, RESERVED10[8], DMACHTDR, DMACHRDR, DMACHTBAR,
  5403. DMACHRBAR;
  5404. };
  5405. #define ETH ((struct stm32_eth *) (uintptr_t) 0x40028000)
  5406. #define BIT(x) ((uint32_t) 1 << (x))
  5407. #define ETH_PKT_SIZE 1540 // Max frame size
  5408. #define ETH_DESC_CNT 4 // Descriptors count
  5409. #define ETH_DS 4 // Descriptor size (words)
  5410. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
  5411. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
  5412. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
  5413. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
  5414. static void (*s_rx)(void *, size_t, void *); // Recv callback
  5415. static void *s_rxdata; // Recv callback data
  5416. enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1 }; // PHY constants
  5417. static inline void spin(volatile uint32_t count) {
  5418. while (count--) asm("nop");
  5419. }
  5420. static uint32_t hclk_get(void);
  5421. static uint8_t cr_guess(uint32_t hclk);
  5422. static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
  5423. ETH->MACMIIAR &= (7 << 2);
  5424. ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6);
  5425. ETH->MACMIIAR |= BIT(0);
  5426. while (ETH->MACMIIAR & BIT(0)) spin(1);
  5427. return ETH->MACMIIDR;
  5428. }
  5429. static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
  5430. ETH->MACMIIDR = val;
  5431. ETH->MACMIIAR &= (7 << 2);
  5432. ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | BIT(1);
  5433. ETH->MACMIIAR |= BIT(0);
  5434. while (ETH->MACMIIAR & BIT(0)) spin(1);
  5435. }
  5436. static bool mip_driver_stm32_init(uint8_t *mac, void *userdata) {
  5437. // Init RX descriptors
  5438. for (int i = 0; i < ETH_DESC_CNT; i++) {
  5439. s_rxdesc[i][0] = BIT(31); // Own
  5440. s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | BIT(14); // 2nd address chained
  5441. s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
  5442. s_rxdesc[i][3] =
  5443. (uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  5444. }
  5445. // Init TX descriptors
  5446. for (int i = 0; i < ETH_DESC_CNT; i++) {
  5447. s_txdesc[i][2] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
  5448. s_txdesc[i][3] =
  5449. (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  5450. }
  5451. ETH->DMABMR |= BIT(0); // Software reset
  5452. while ((ETH->DMABMR & BIT(0)) != 0) spin(1); // Wait until done
  5453. // NOTE(cpq): we do not use extended descriptor bit 7, and do not use
  5454. // hardware checksum. Therefore, descriptor size is 4, not 8
  5455. // ETH->DMABMR = BIT(13) | BIT(16) | BIT(22) | BIT(23) | BIT(25);
  5456. ETH->MACIMR = BIT(3) | BIT(9); // Mask timestamp & PMT IT
  5457. ETH->MACMIIAR = cr_guess(hclk_get()) << 2; // MDC clock
  5458. ETH->MACFCR = BIT(7); // Disable zero quarta pause
  5459. ETH->MACFFR = BIT(31); // Receive all
  5460. eth_write_phy(PHY_ADDR, PHY_BCR, BIT(15)); // Reset PHY
  5461. eth_write_phy(PHY_ADDR, PHY_BCR, BIT(12)); // Set autonegotiation
  5462. ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
  5463. ETH->DMATDLAR = (uint32_t) (uintptr_t) s_txdesc; // RX descriptors
  5464. ETH->DMAIER = BIT(6) | BIT(16); // RIE, NISE
  5465. ETH->MACCR = BIT(2) | BIT(3) | BIT(11) | BIT(14); // RE, TE, Duplex, Fast
  5466. ETH->DMAOMR = BIT(1) | BIT(13) | BIT(21) | BIT(25); // SR, ST, TSF, RSF
  5467. // TODO(cpq): setup MAC filtering
  5468. (void) userdata, (void) mac;
  5469. return true;
  5470. }
  5471. static void mip_driver_stm32_setrx(void (*rx)(void *, size_t, void *),
  5472. void *rxdata) {
  5473. s_rx = rx;
  5474. s_rxdata = rxdata;
  5475. }
  5476. static uint32_t s_txno;
  5477. static size_t mip_driver_stm32_tx(const void *buf, size_t len, void *userdata) {
  5478. if (len > sizeof(s_txbuf[s_txno])) {
  5479. printf("%s: frame too big, %ld\n", __func__, (long) len);
  5480. len = 0; // Frame is too big
  5481. } else if ((s_txdesc[s_txno][0] & BIT(31))) {
  5482. printf("%s: no free descr\n", __func__);
  5483. len = 0; // All descriptors are busy, fail
  5484. } else {
  5485. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  5486. s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
  5487. s_txdesc[s_txno][0] = BIT(20) | BIT(28) | BIT(29) | BIT(30); // Chain,FS,LS
  5488. s_txdesc[s_txno][0] |= BIT(31); // Set OWN bit - let DMA take over
  5489. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  5490. }
  5491. uint32_t sr = ETH->DMASR;
  5492. if (sr & BIT(2)) ETH->DMASR = BIT(2), ETH->DMATPDR = 0; // Resume
  5493. if (sr & BIT(5)) ETH->DMASR = BIT(5), ETH->DMATPDR = 0; // if busy
  5494. if (len == 0) printf("E: D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) sr);
  5495. return len;
  5496. (void) userdata;
  5497. }
  5498. static bool mip_driver_stm32_up(void *userdata) {
  5499. uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
  5500. (void) userdata;
  5501. return bsr & BIT(2) ? 1 : 0;
  5502. }
  5503. void ETH_IRQHandler(void);
  5504. void ETH_IRQHandler(void) {
  5505. volatile uint32_t sr = ETH->DMASR;
  5506. if (sr & BIT(6)) { // Frame received, loop
  5507. for (uint32_t i = 0; i < ETH_DESC_CNT; i++) {
  5508. if (s_rxdesc[i][0] & BIT(31)) continue;
  5509. uint32_t len = ((s_rxdesc[i][0] >> 16) & (BIT(14) - 1));
  5510. // printf("%lx %lu %lx %lx\n", i, len, s_rxdesc[i][0], sr);
  5511. if (s_rx != NULL) s_rx(s_rxbuf[i], len > 4 ? len - 4 : len, s_rxdata);
  5512. s_rxdesc[i][0] = BIT(31);
  5513. }
  5514. }
  5515. if (sr & BIT(7)) ETH->DMARPDR = 0; // Resume RX
  5516. ETH->DMASR = sr & ~(BIT(2) | BIT(7)); // Clear status
  5517. }
  5518. struct mip_driver mip_driver_stm32 = {.init = mip_driver_stm32_init,
  5519. .tx = mip_driver_stm32_tx,
  5520. .setrx = mip_driver_stm32_setrx,
  5521. .up = mip_driver_stm32_up};
  5522. /* Calculate HCLK from clock settings,
  5523. valid for STM32F74xxx/75xxx (5.3) and STM32F42xxx/43xxx (6.3) */
  5524. static const uint8_t ahbptab[8] = {1, 2, 3, 4, 6, 7, 8, 9}; // log2(div)
  5525. struct rcc {
  5526. volatile uint32_t CR, PLLCFGR, CFGR;
  5527. };
  5528. #define RCC ((struct rcc *) 0x40023800)
  5529. static uint32_t hclk_get(void) {
  5530. uint32_t clk = 0;
  5531. if (RCC->CFGR & (1 << 2)) {
  5532. clk = MG_STM32_CLK_HSE;
  5533. } else if (RCC->CFGR & (1 << 3)) {
  5534. uint32_t vco, m, n, p;
  5535. m = (RCC->PLLCFGR & (0x3FUL << 0)) >> 0;
  5536. n = (RCC->PLLCFGR & (0x1FFUL << 6)) >> 6;
  5537. p = (((RCC->PLLCFGR & (0x03UL << 16)) >> 16) + 1) * 2;
  5538. if (RCC->PLLCFGR & (1UL << 22))
  5539. clk = MG_STM32_CLK_HSE;
  5540. else
  5541. clk = MG_STM32_CLK_HSI;
  5542. vco = (uint32_t)((uint64_t)(((uint32_t) clk * (uint32_t) n)) /
  5543. ((uint32_t) m));
  5544. clk = vco / p;
  5545. } else {
  5546. clk = MG_STM32_CLK_HSI;
  5547. }
  5548. int hpre = (RCC->CFGR & (0x0F << 4)) >> 4;
  5549. if (hpre < 8) return clk;
  5550. return ((uint32_t) clk) >> ahbptab[hpre - 8];
  5551. }
  5552. /* Guess CR from HCLK:
  5553. MDC clock is generated from HCLK (AHB); as per 802.3, it must not exceed 2.5MHz
  5554. As the AHB clock can be (and usually is) derived from the HSI (internal RC),
  5555. and it can go above specs, the datasheets specify a range of frequencies and
  5556. activate one of a series of dividers to keep the MDC clock safely below 2.5MHz.
  5557. We guess a divider setting based on HCLK with a +5% drift.
  5558. If the user uses a different clock from our defaults, needs to set the macros on top
  5559. Valid for STM32F74xxx/75xxx (38.8.1) and STM32F42xxx/43xxx (33.8.1) (both 4.5% worst case drift) */
  5560. #define CRDTAB_LEN 6
  5561. static const uint8_t crdtab[CRDTAB_LEN][2] = {
  5562. // [{setting, div ratio},...]
  5563. {2, 16}, {3, 26}, {0, 42}, {1, 62}, {4, 102}, {5, 124},
  5564. };
  5565. static uint8_t cr_guess(uint32_t hclk) {
  5566. MG_DEBUG(("HCLK: %u", hclk));
  5567. if (hclk < 25000000) {
  5568. MG_ERROR(("HCLK too low"));
  5569. return CRDTAB_LEN;
  5570. }
  5571. for (int i = 0; i < CRDTAB_LEN; i++)
  5572. if (hclk / crdtab[i][1] <= 2375000UL) return crdtab[i][0]; // 2.5MHz - 5%
  5573. MG_ERROR(("HCLK too high"));
  5574. return CRDTAB_LEN;
  5575. }
  5576. #endif // MG_ENABLE_MIP
  5577. #ifdef MG_ENABLE_LINES
  5578. #line 1 "mip/driver_w5500.c"
  5579. #endif
  5580. #if MG_ENABLE_MIP
  5581. enum { W5500_CR = 0, W5500_S0 = 1, W5500_TX0 = 2, W5500_RX0 = 3 };
  5582. static void w5500_txn(struct mip_spi *s, uint8_t block, uint16_t addr, bool wr,
  5583. void *buf, size_t len) {
  5584. uint8_t *p = buf, cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255),
  5585. (uint8_t) ((block << 3) | (wr ? 4 : 0))};
  5586. s->begin(s->spi);
  5587. for (size_t i = 0; i < sizeof(cmd); i++) s->txn(s->spi, cmd[i]);
  5588. for (size_t i = 0; i < len; i++) {
  5589. uint8_t r = s->txn(s->spi, p[i]);
  5590. if (!wr) p[i] = r;
  5591. }
  5592. s->end(s->spi);
  5593. }
  5594. // clang-format off
  5595. static void w5500_wn(struct mip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); }
  5596. static void w5500_w1(struct mip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); }
  5597. static void w5500_w2(struct mip_spi *s, uint8_t block, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5500_wn(s, block, addr, buf, sizeof(buf)); }
  5598. static void w5500_rn(struct mip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); }
  5599. static uint8_t w5500_r1(struct mip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; }
  5600. static uint16_t w5500_r2(struct mip_spi *s, uint8_t block, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5500_rn(s, block, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); }
  5601. // clang-format on
  5602. static size_t w5500_rx(void *buf, size_t buflen, void *data) {
  5603. struct mip_spi *s = (struct mip_spi *) data;
  5604. uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2; // Read recv len
  5605. while ((n2 = w5500_r2(s, W5500_S0, 0x26)) > n) n = n2; // Until it is stable
  5606. // printf("RSR: %d\n", (int) n);
  5607. if (n > 0) {
  5608. uint16_t ptr = w5500_r2(s, W5500_S0, 0x28); // Get read pointer
  5609. n = w5500_r2(s, W5500_RX0, ptr); // Read frame length
  5610. if (n <= len + 2) r = n - 2, w5500_rn(s, W5500_RX0, ptr + 2, buf, r);
  5611. w5500_w2(s, W5500_S0, 0x28, ptr + n); // Advance read pointer
  5612. w5500_w1(s, W5500_S0, 1, 0x40); // Sock0 CR -> RECV
  5613. // printf(" RX_RD: tot=%u n=%u r=%u\n", n2, n, r);
  5614. }
  5615. return r;
  5616. }
  5617. static size_t w5500_tx(const void *buf, size_t buflen, void *data) {
  5618. struct mip_spi *s = (struct mip_spi *) data;
  5619. uint16_t n = 0, len = (uint16_t) buflen;
  5620. while (n < len) n = w5500_r2(s, W5500_S0, 0x20); // Wait for space
  5621. uint16_t ptr = w5500_r2(s, W5500_S0, 0x24); // Get write pointer
  5622. w5500_wn(s, W5500_TX0, ptr, (void *) buf, len); // Write data
  5623. w5500_w2(s, W5500_S0, 0x24, ptr + len); // Advance write pointer
  5624. w5500_w1(s, W5500_S0, 1, 0x20); // Sock0 CR -> SEND
  5625. for (int i = 0; i < 40; i++) {
  5626. uint8_t ir = w5500_r1(s, W5500_S0, 2); // Read S0 IR
  5627. if (ir == 0) continue;
  5628. // printf("IR %d, len=%d, free=%d, ptr %d\n", ir, (int) len, (int) n, ptr);
  5629. w5500_w1(s, W5500_S0, 2, ir); // Write S0 IR: clear it!
  5630. if (ir & 8) len = 0; // Timeout. Report error
  5631. if (ir & (16 | 8)) break; // Stop on SEND_OK or timeout
  5632. }
  5633. return len;
  5634. }
  5635. static bool w5500_init(uint8_t *mac, void *data) {
  5636. struct mip_spi *s = (struct mip_spi *) data;
  5637. s->end(s->spi);
  5638. w5500_w1(s, W5500_CR, 0, 0x80); // Reset chip: CR -> 0x80
  5639. w5500_w1(s, W5500_CR, 0x2e, 0); // CR PHYCFGR -> reset
  5640. w5500_w1(s, W5500_CR, 0x2e, 0xf8); // CR PHYCFGR -> set
  5641. // w5500_wn(s, W5500_CR, 9, s->mac, 6); // Set source MAC
  5642. w5500_w1(s, W5500_S0, 0x1e, 16); // Sock0 RX buf size
  5643. w5500_w1(s, W5500_S0, 0x1f, 16); // Sock0 TX buf size
  5644. w5500_w1(s, W5500_S0, 0, 4); // Sock0 MR -> MACRAW
  5645. w5500_w1(s, W5500_S0, 1, 1); // Sock0 CR -> OPEN
  5646. return w5500_r1(s, W5500_S0, 3) == 0x42; // Sock0 SR == MACRAW
  5647. (void) mac;
  5648. }
  5649. static bool w5500_up(void *data) {
  5650. uint8_t phycfgr = w5500_r1((struct mip_spi *) data, W5500_CR, 0x2e);
  5651. return phycfgr & 1; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up)
  5652. }
  5653. struct mip_driver mip_driver_w5500 = {
  5654. .init = w5500_init, .tx = w5500_tx, .rx = w5500_rx, .up = w5500_up};
  5655. #endif
  5656. #ifdef MG_ENABLE_LINES
  5657. #line 1 "mip/mip.c"
  5658. #endif
  5659. #if MG_ENABLE_MIP
  5660. #if defined(_MSC_VER) || defined(ARDUINO)
  5661. #define _Atomic
  5662. #else
  5663. #include <stdatomic.h>
  5664. #endif
  5665. #define MIP_ETHEMERAL_PORT 49152
  5666. #define U16(ptr) ((((uint16_t) (ptr)[0]) << 8) | (ptr)[1])
  5667. #define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
  5668. #ifndef MIP_ARP_ENTRIES
  5669. #define MIP_ARP_ENTRIES 5 // Number of ARP cache entries. Maximum 21
  5670. #endif
  5671. #define MIP_ARP_CS (2 + 12 * MIP_ARP_ENTRIES) // ARP cache size
  5672. struct str {
  5673. uint8_t *buf;
  5674. size_t len;
  5675. };
  5676. // Receive queue - single producer, single consumer queue. Interrupt-based
  5677. // drivers copy received frames to the queue in interrupt context. mip_poll()
  5678. // function runs in event loop context, reads from the queue
  5679. struct queue {
  5680. uint8_t *buf;
  5681. size_t len;
  5682. volatile _Atomic size_t tail, head;
  5683. };
  5684. // Network interface
  5685. struct mip_if {
  5686. uint8_t mac[6]; // MAC address. Must be set to a valid MAC
  5687. uint32_t ip, mask, gw; // IP address, mask, default gateway. Can be 0
  5688. struct str rx; // Output (TX) buffer
  5689. struct str tx; // Input (RX) buffer
  5690. bool use_dhcp; // Enable DCHP
  5691. struct mip_driver *driver; // Low level driver
  5692. void *driver_data; // Driver-specific data
  5693. struct mg_mgr *mgr; // Mongoose event manager
  5694. // Internal state, user can use it but should not change it
  5695. uint64_t curtime; // Last poll timestamp in millis
  5696. uint64_t timer; // Timer
  5697. uint8_t arp_cache[MIP_ARP_CS]; // Each entry is 12 bytes
  5698. uint16_t eport; // Next ephemeral port
  5699. int state; // Current state
  5700. #define MIP_STATE_DOWN 0 // Interface is down
  5701. #define MIP_STATE_UP 1 // Interface is up
  5702. #define MIP_STATE_READY 2 // Interface is up and has IP
  5703. struct queue queue; // Receive queue
  5704. };
  5705. #pragma pack(push, 1)
  5706. struct lcp {
  5707. uint8_t addr, ctrl, proto[2], code, id, len[2];
  5708. };
  5709. struct eth {
  5710. uint8_t dst[6]; // Destination MAC address
  5711. uint8_t src[6]; // Source MAC address
  5712. uint16_t type; // Ethernet type
  5713. };
  5714. struct ip {
  5715. uint8_t ver; // Version
  5716. uint8_t tos; // Unused
  5717. uint16_t len; // Length
  5718. uint16_t id; // Unused
  5719. uint16_t frag; // Fragmentation
  5720. uint8_t ttl; // Time to live
  5721. uint8_t proto; // Upper level protocol
  5722. uint16_t csum; // Checksum
  5723. uint32_t src; // Source IP
  5724. uint32_t dst; // Destination IP
  5725. };
  5726. struct ip6 {
  5727. uint8_t ver; // Version
  5728. uint8_t opts[3]; // Options
  5729. uint16_t len; // Length
  5730. uint8_t proto; // Upper level protocol
  5731. uint8_t ttl; // Time to live
  5732. uint8_t src[16]; // Source IP
  5733. uint8_t dst[16]; // Destination IP
  5734. };
  5735. struct icmp {
  5736. uint8_t type;
  5737. uint8_t code;
  5738. uint16_t csum;
  5739. };
  5740. struct arp {
  5741. uint16_t fmt; // Format of hardware address
  5742. uint16_t pro; // Format of protocol address
  5743. uint8_t hlen; // Length of hardware address
  5744. uint8_t plen; // Length of protocol address
  5745. uint16_t op; // Operation
  5746. uint8_t sha[6]; // Sender hardware address
  5747. uint32_t spa; // Sender protocol address
  5748. uint8_t tha[6]; // Target hardware address
  5749. uint32_t tpa; // Target protocol address
  5750. };
  5751. struct tcp {
  5752. uint16_t sport; // Source port
  5753. uint16_t dport; // Destination port
  5754. uint32_t seq; // Sequence number
  5755. uint32_t ack; // Acknowledgement number
  5756. uint8_t off; // Data offset
  5757. uint8_t flags; // TCP flags
  5758. #define TH_FIN 0x01
  5759. #define TH_SYN 0x02
  5760. #define TH_RST 0x04
  5761. #define TH_PUSH 0x08
  5762. #define TH_ACK 0x10
  5763. #define TH_URG 0x20
  5764. #define TH_ECE 0x40
  5765. #define TH_CWR 0x80
  5766. uint16_t win; // Window
  5767. uint16_t csum; // Checksum
  5768. uint16_t urp; // Urgent pointer
  5769. };
  5770. struct udp {
  5771. uint16_t sport; // Source port
  5772. uint16_t dport; // Destination port
  5773. uint16_t len; // UDP length
  5774. uint16_t csum; // UDP checksum
  5775. };
  5776. struct dhcp {
  5777. uint8_t op, htype, hlen, hops;
  5778. uint32_t xid;
  5779. uint16_t secs, flags;
  5780. uint32_t ciaddr, yiaddr, siaddr, giaddr;
  5781. uint8_t hwaddr[208];
  5782. uint32_t magic;
  5783. uint8_t options[32];
  5784. };
  5785. #pragma pack(pop)
  5786. struct pkt {
  5787. struct str raw; // Raw packet data
  5788. struct str pay; // Payload data
  5789. struct eth *eth;
  5790. struct llc *llc;
  5791. struct arp *arp;
  5792. struct ip *ip;
  5793. struct ip6 *ip6;
  5794. struct icmp *icmp;
  5795. struct tcp *tcp;
  5796. struct udp *udp;
  5797. struct dhcp *dhcp;
  5798. };
  5799. static void q_copyin(struct queue *q, const uint8_t *buf, size_t len,
  5800. size_t head) {
  5801. size_t i = 0, left = q->len - head;
  5802. for (; i < len && i < left; i++) q->buf[head + i] = buf[i];
  5803. for (; i < len; i++) q->buf[i - left] = buf[i];
  5804. }
  5805. static void q_copyout(struct queue *q, uint8_t *buf, size_t len, size_t tail) {
  5806. size_t i = 0, left = q->len - tail;
  5807. for (; i < len && i < left; i++) buf[i] = q->buf[tail + i];
  5808. for (; i < len; i++) buf[i] = q->buf[i - left];
  5809. }
  5810. static bool q_write(struct queue *q, const void *buf, size_t len) {
  5811. bool success = false;
  5812. size_t left = q->len - q->head + q->tail;
  5813. if (len + sizeof(size_t) <= left) {
  5814. q_copyin(q, (uint8_t *) &len, sizeof(len), q->head);
  5815. q_copyin(q, (uint8_t *) buf, len, (q->head + sizeof(size_t)) % q->len);
  5816. q->head = (q->head + sizeof(len) + len) % q->len;
  5817. success = true;
  5818. }
  5819. return success;
  5820. }
  5821. static size_t q_avail(struct queue *q) {
  5822. size_t n = 0;
  5823. if (q->tail != q->head) q_copyout(q, (uint8_t *) &n, sizeof(n), q->tail);
  5824. return n;
  5825. }
  5826. static size_t q_read(struct queue *q, void *buf) {
  5827. size_t n = q_avail(q);
  5828. if (n > 0) {
  5829. q_copyout(q, (uint8_t *) buf, n, (q->tail + sizeof(n)) % q->len);
  5830. q->tail = (q->tail + sizeof(n) + n) % q->len;
  5831. }
  5832. return n;
  5833. }
  5834. static struct str mkstr(void *buf, size_t len) {
  5835. struct str str = {(uint8_t *) buf, len};
  5836. return str;
  5837. }
  5838. static void mkpay(struct pkt *pkt, void *p) {
  5839. pkt->pay = mkstr(p, (size_t) (&pkt->raw.buf[pkt->raw.len] - (uint8_t *) p));
  5840. }
  5841. static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
  5842. const uint8_t *p = (const uint8_t *) buf;
  5843. for (size_t i = 0; i < len; i++) sum += i & 1 ? p[i] : (uint32_t) (p[i] << 8);
  5844. return sum;
  5845. }
  5846. static uint16_t csumfin(uint32_t sum) {
  5847. while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
  5848. return mg_htons(~sum & 0xffff);
  5849. }
  5850. static uint16_t ipcsum(const void *buf, size_t len) {
  5851. uint32_t sum = csumup(0, buf, len);
  5852. return csumfin(sum);
  5853. }
  5854. // ARP cache is organised as a doubly linked list. A successful cache lookup
  5855. // moves an entry to the head of the list. New entries are added by replacing
  5856. // the last entry in the list with a new IP/MAC.
  5857. // ARP cache format: | prev | next | Entry0 | Entry1 | .... | EntryN |
  5858. // ARP entry format: | prev | next | IP (4bytes) | MAC (6bytes) |
  5859. // prev and next are 1-byte offsets in the cache, so cache size is max 256 bytes
  5860. // ARP entry size is 12 bytes
  5861. static void arp_cache_init(uint8_t *p, int n, int size) {
  5862. for (int i = 0; i < n; i++) p[2 + i * size] = (uint8_t) (2 + (i - 1) * size);
  5863. for (int i = 0; i < n; i++) p[3 + i * size] = (uint8_t) (2 + (i + 1) * size);
  5864. p[0] = p[2] = (uint8_t) (2 + (n - 1) * size);
  5865. p[1] = p[3 + (n - 1) * size] = 2;
  5866. }
  5867. static uint8_t *arp_cache_find(struct mip_if *ifp, uint32_t ip) {
  5868. uint8_t *p = ifp->arp_cache;
  5869. if (ip == 0) return NULL;
  5870. if (p[0] == 0 || p[1] == 0) arp_cache_init(p, MIP_ARP_ENTRIES, 12);
  5871. for (uint8_t i = 0, j = p[1]; i < MIP_ARP_ENTRIES; i++, j = p[j + 1]) {
  5872. if (memcmp(p + j + 2, &ip, sizeof(ip)) == 0) {
  5873. p[1] = j, p[0] = p[j]; // Found entry! Point list head to us
  5874. // MG_DEBUG(("ARP find: %#lx @ %x:%x:%x:%x:%x:%x\n", (long) ip, p[j + 6],
  5875. // p[j + 7], p[j + 8], p[j + 9], p[j + 10], p[j + 11]));
  5876. return p + j + 6; // And return MAC address
  5877. }
  5878. }
  5879. return NULL;
  5880. }
  5881. static void arp_cache_add(struct mip_if *ifp, uint32_t ip, uint8_t mac[6]) {
  5882. uint8_t *p = ifp->arp_cache;
  5883. if (ip == 0 || ip == ~0U) return; // Bad IP
  5884. if (arp_cache_find(ifp, ip) != NULL) return; // Already exists, do nothing
  5885. memcpy(p + p[0] + 2, &ip, sizeof(ip)); // Replace last entry: IP address
  5886. memcpy(p + p[0] + 6, mac, 6); // And MAC address
  5887. p[1] = p[0], p[0] = p[p[1]]; // Point list head to us
  5888. MG_DEBUG(("ARP cache: added %#lx @ %x:%x:%x:%x:%x:%x", (long) mg_htonl(ip),
  5889. mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]));
  5890. }
  5891. static void arp_ask(struct mip_if *ifp, uint32_t ip) {
  5892. struct eth *eth = (struct eth *) ifp->tx.buf;
  5893. struct arp *arp = (struct arp *) (eth + 1);
  5894. memset(eth->dst, 255, sizeof(eth->dst));
  5895. memcpy(eth->src, ifp->mac, sizeof(eth->src));
  5896. eth->type = mg_htons(0x806);
  5897. memset(arp, 0, sizeof(*arp));
  5898. arp->fmt = mg_htons(1), arp->pro = mg_htons(0x800), arp->hlen = 6,
  5899. arp->plen = 4;
  5900. arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
  5901. memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
  5902. ifp->driver->tx(eth, PDIFF(eth, arp + 1), ifp->driver_data);
  5903. }
  5904. static void onstatechange(struct mip_if *ifp) {
  5905. if (ifp->state == MIP_STATE_READY) {
  5906. char buf[40];
  5907. struct mg_addr addr = {.ip = ifp->ip};
  5908. MG_INFO(("READY, IP: %s", mg_ntoa(&addr, buf, sizeof(buf))));
  5909. arp_ask(ifp, ifp->gw);
  5910. } else if (ifp->state == MIP_STATE_UP) {
  5911. MG_ERROR(("Network up"));
  5912. } else if (ifp->state == MIP_STATE_DOWN) {
  5913. MG_ERROR(("Network down"));
  5914. }
  5915. }
  5916. static struct ip *tx_ip(struct mip_if *ifp, uint8_t proto, uint32_t ip_src,
  5917. uint32_t ip_dst, size_t plen) {
  5918. struct eth *eth = (struct eth *) ifp->tx.buf;
  5919. struct ip *ip = (struct ip *) (eth + 1);
  5920. uint8_t *mac = arp_cache_find(ifp, ip_dst); // Dst IP in ARP cache ?
  5921. if (!mac) mac = arp_cache_find(ifp, ifp->gw); // No, use gateway
  5922. if (mac) memcpy(eth->dst, mac, sizeof(eth->dst)); // Found? Use it
  5923. if (!mac) memset(eth->dst, 255, sizeof(eth->dst)); // No? Use broadcast
  5924. memcpy(eth->src, ifp->mac, sizeof(eth->src)); // TODO(cpq): ARP lookup
  5925. eth->type = mg_htons(0x800);
  5926. memset(ip, 0, sizeof(*ip));
  5927. ip->ver = 0x45; // Version 4, header length 5 words
  5928. ip->frag = 0x40; // Don't fragment
  5929. ip->len = mg_htons((uint16_t) (sizeof(*ip) + plen));
  5930. ip->ttl = 64;
  5931. ip->proto = proto;
  5932. ip->src = ip_src;
  5933. ip->dst = ip_dst;
  5934. ip->csum = ipcsum(ip, sizeof(*ip));
  5935. return ip;
  5936. }
  5937. static void tx_udp(struct mip_if *ifp, uint32_t ip_src, uint16_t sport,
  5938. uint32_t ip_dst, uint16_t dport, const void *buf,
  5939. size_t len) {
  5940. struct ip *ip = tx_ip(ifp, 17, ip_src, ip_dst, len + sizeof(struct udp));
  5941. struct udp *udp = (struct udp *) (ip + 1);
  5942. // MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
  5943. udp->sport = sport;
  5944. udp->dport = dport;
  5945. udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
  5946. udp->csum = 0;
  5947. uint32_t cs = csumup(0, udp, sizeof(*udp));
  5948. cs = csumup(cs, buf, len);
  5949. cs = csumup(cs, &ip->src, sizeof(ip->src));
  5950. cs = csumup(cs, &ip->dst, sizeof(ip->dst));
  5951. cs += (uint32_t) (ip->proto + sizeof(*udp) + len);
  5952. udp->csum = csumfin(cs);
  5953. memmove(udp + 1, buf, len);
  5954. // MG_DEBUG(("UDP LEN %d %d\n", (int) len, (int) ifp->frame_len));
  5955. ifp->driver->tx(ifp->tx.buf,
  5956. sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len,
  5957. ifp->driver_data);
  5958. }
  5959. static void tx_dhcp(struct mip_if *ifp, uint32_t src, uint32_t dst,
  5960. uint8_t *opts, size_t optslen) {
  5961. struct dhcp dhcp = {.op = 1,
  5962. .htype = 1,
  5963. .hlen = 6,
  5964. .ciaddr = src,
  5965. .magic = mg_htonl(0x63825363)};
  5966. memcpy(&dhcp.hwaddr, ifp->mac, sizeof(ifp->mac));
  5967. memcpy(&dhcp.xid, ifp->mac + 2, sizeof(dhcp.xid));
  5968. memcpy(&dhcp.options, opts, optslen);
  5969. tx_udp(ifp, src, mg_htons(68), dst, mg_htons(67), &dhcp, sizeof(dhcp));
  5970. }
  5971. static void tx_dhcp_request(struct mip_if *ifp, uint32_t src, uint32_t dst) {
  5972. uint8_t opts[] = {
  5973. 53, 1, 3, // Type: DHCP request
  5974. 55, 2, 1, 3, // GW and mask
  5975. 12, 3, 'm', 'i', 'p', // Host name: "mip"
  5976. 54, 4, 0, 0, 0, 0, // DHCP server ID
  5977. 50, 4, 0, 0, 0, 0, // Requested IP
  5978. 255 // End of options
  5979. };
  5980. memcpy(opts + 14, &dst, sizeof(dst));
  5981. memcpy(opts + 20, &src, sizeof(src));
  5982. tx_dhcp(ifp, src, dst, opts, sizeof(opts));
  5983. }
  5984. static void tx_dhcp_discover(struct mip_if *ifp) {
  5985. uint8_t opts[] = {
  5986. 53, 1, 1, // Type: DHCP discover
  5987. 55, 2, 1, 3, // Parameters: ip, mask
  5988. 255 // End of options
  5989. };
  5990. tx_dhcp(ifp, 0, 0xffffffff, opts, sizeof(opts));
  5991. }
  5992. static void rx_arp(struct mip_if *ifp, struct pkt *pkt) {
  5993. if (pkt->arp->op == mg_htons(1) && pkt->arp->tpa == ifp->ip) {
  5994. // ARP request. Make a response, then send
  5995. struct eth *eth = (struct eth *) ifp->tx.buf;
  5996. struct arp *arp = (struct arp *) (eth + 1);
  5997. MG_DEBUG(("ARP op %d %#x %#x", mg_htons(arp->op), arp->spa, arp->tpa));
  5998. memcpy(eth->dst, pkt->eth->src, sizeof(eth->dst));
  5999. memcpy(eth->src, ifp->mac, sizeof(eth->src));
  6000. eth->type = mg_htons(0x806);
  6001. *arp = *pkt->arp;
  6002. arp->op = mg_htons(2);
  6003. memcpy(arp->tha, pkt->arp->sha, sizeof(pkt->arp->tha));
  6004. memcpy(arp->sha, ifp->mac, sizeof(pkt->arp->sha));
  6005. arp->tpa = pkt->arp->spa;
  6006. arp->spa = ifp->ip;
  6007. MG_DEBUG(("ARP response: we're %#lx", (long) mg_ntohl(ifp->ip)));
  6008. ifp->driver->tx(ifp->tx.buf, PDIFF(eth, arp + 1), ifp->driver_data);
  6009. } else if (pkt->arp->op == mg_htons(2)) {
  6010. if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
  6011. // MG_INFO(("ARP RESPONSE"));
  6012. arp_cache_add(ifp, pkt->arp->spa, pkt->arp->sha);
  6013. }
  6014. }
  6015. static void rx_icmp(struct mip_if *ifp, struct pkt *pkt) {
  6016. // MG_DEBUG(("ICMP %d\n", (int) len));
  6017. if (pkt->icmp->type == 8 && pkt->ip->dst == ifp->ip) {
  6018. struct ip *ip = tx_ip(ifp, 1, ifp->ip, pkt->ip->src,
  6019. sizeof(struct icmp) + pkt->pay.len);
  6020. struct icmp *icmp = (struct icmp *) (ip + 1);
  6021. memset(icmp, 0, sizeof(*icmp)); // Important - set csum to 0
  6022. memcpy(icmp + 1, pkt->pay.buf, pkt->pay.len);
  6023. icmp->csum = ipcsum(icmp, sizeof(*icmp) + pkt->pay.len);
  6024. ifp->driver->tx(ifp->tx.buf, PDIFF(ifp->tx.buf, icmp + 1) + pkt->pay.len,
  6025. ifp->driver_data);
  6026. }
  6027. }
  6028. static void rx_dhcp(struct mip_if *ifp, struct pkt *pkt) {
  6029. uint32_t ip = 0, gw = 0, mask = 0;
  6030. uint8_t *p = pkt->dhcp->options, *end = &pkt->raw.buf[pkt->raw.len];
  6031. if (end < (uint8_t *) (pkt->dhcp + 1)) return;
  6032. // MG_DEBUG(("DHCP %u\n", (unsigned) pkt->raw.len));
  6033. while (p < end && p[0] != 255) {
  6034. if (p[0] == 1 && p[1] == sizeof(ifp->mask)) {
  6035. memcpy(&mask, p + 2, sizeof(mask));
  6036. // MG_DEBUG(("MASK %x\n", mask));
  6037. } else if (p[0] == 3 && p[1] == sizeof(ifp->gw)) {
  6038. memcpy(&gw, p + 2, sizeof(gw));
  6039. ip = pkt->dhcp->yiaddr;
  6040. // MG_DEBUG(("IP %x GW %x\n", ip, gw));
  6041. }
  6042. p += p[1] + 2;
  6043. }
  6044. if (ip && mask && gw && ifp->ip == 0) {
  6045. // MG_DEBUG(("DHCP offer ip %#08lx mask %#08lx gw %#08lx\n",
  6046. // (long) ip, (long) mask, (long) gw));
  6047. arp_cache_add(ifp, pkt->dhcp->siaddr, ((struct eth *) pkt->raw.buf)->src);
  6048. ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
  6049. ifp->state = MIP_STATE_READY;
  6050. onstatechange(ifp);
  6051. tx_dhcp_request(ifp, ip, pkt->dhcp->siaddr);
  6052. }
  6053. }
  6054. static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
  6055. bool lsn) {
  6056. struct mg_connection *c = NULL;
  6057. for (c = mgr->conns; c != NULL; c = c->next) {
  6058. if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) break;
  6059. if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport &&
  6060. lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport))
  6061. break;
  6062. }
  6063. return c;
  6064. }
  6065. static void rx_udp(struct mip_if *ifp, struct pkt *pkt) {
  6066. struct mg_connection *c = getpeer(ifp->mgr, pkt, true);
  6067. if (c == NULL) {
  6068. // No UDP listener on this port. Should send ICMP, but keep silent.
  6069. } else if (c != NULL) {
  6070. c->rem.port = pkt->udp->sport;
  6071. c->rem.ip = pkt->ip->src;
  6072. if (c->recv.len >= MG_MAX_RECV_SIZE) {
  6073. mg_error(c, "max_recv_buf_size reached");
  6074. } else if (c->recv.size - c->recv.len < pkt->pay.len &&
  6075. !mg_iobuf_resize(&c->recv, c->recv.len + pkt->pay.len)) {
  6076. mg_error(c, "oom");
  6077. } else {
  6078. memcpy(&c->recv.buf[c->recv.len], pkt->pay.buf, pkt->pay.len);
  6079. c->recv.len += pkt->pay.len;
  6080. struct mg_str evd = mg_str_n((char *) pkt->pay.buf, pkt->pay.len);
  6081. mg_call(c, MG_EV_READ, &evd);
  6082. }
  6083. }
  6084. }
  6085. struct tcpstate {
  6086. uint32_t seq, ack;
  6087. time_t expire;
  6088. };
  6089. static size_t tx_tcp(struct mip_if *ifp, uint32_t dst_ip, uint8_t flags,
  6090. uint16_t sport, uint16_t dport, uint32_t seq, uint32_t ack,
  6091. const void *buf, size_t len) {
  6092. struct ip *ip = tx_ip(ifp, 6, ifp->ip, dst_ip, sizeof(struct tcp) + len);
  6093. struct tcp *tcp = (struct tcp *) (ip + 1);
  6094. memset(tcp, 0, sizeof(*tcp));
  6095. memmove(tcp + 1, buf, len);
  6096. tcp->sport = sport;
  6097. tcp->dport = dport;
  6098. tcp->seq = seq;
  6099. tcp->ack = ack;
  6100. tcp->flags = flags;
  6101. tcp->win = mg_htons(8192);
  6102. tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
  6103. uint32_t cs = 0;
  6104. uint16_t n = (uint16_t) (sizeof(*tcp) + len);
  6105. uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
  6106. cs = csumup(cs, tcp, n);
  6107. cs = csumup(cs, &ip->src, sizeof(ip->src));
  6108. cs = csumup(cs, &ip->dst, sizeof(ip->dst));
  6109. cs = csumup(cs, pseudo, sizeof(pseudo));
  6110. tcp->csum = csumfin(cs);
  6111. return ifp->driver->tx(ifp->tx.buf, PDIFF(ifp->tx.buf, tcp + 1) + len,
  6112. ifp->driver_data);
  6113. }
  6114. static size_t tx_tcp_pkt(struct mip_if *ifp, struct pkt *pkt, uint8_t flags,
  6115. uint32_t seq, const void *buf, size_t len) {
  6116. uint32_t delta = (pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0;
  6117. return tx_tcp(ifp, pkt->ip->src, flags, pkt->tcp->dport, pkt->tcp->sport, seq,
  6118. mg_htonl(mg_ntohl(pkt->tcp->seq) + delta), buf, len);
  6119. }
  6120. static struct mg_connection *accept_conn(struct mg_connection *lsn,
  6121. struct pkt *pkt) {
  6122. struct mg_connection *c = mg_alloc_conn(lsn->mgr);
  6123. struct tcpstate *s = (struct tcpstate *) (c + 1);
  6124. s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
  6125. c->rem.ip = pkt->ip->src;
  6126. c->rem.port = pkt->tcp->sport;
  6127. MG_DEBUG(("%lu accepted %lx:%hx", c->id, c->rem.ip, c->rem.port));
  6128. LIST_ADD_HEAD(struct mg_connection, &lsn->mgr->conns, c);
  6129. c->fd = (void *) (size_t) mg_ntohl(pkt->tcp->ack);
  6130. c->is_accepted = 1;
  6131. c->is_hexdumping = lsn->is_hexdumping;
  6132. c->pfn = lsn->pfn;
  6133. c->loc = lsn->loc;
  6134. c->pfn_data = lsn->pfn_data;
  6135. c->fn = lsn->fn;
  6136. c->fn_data = lsn->fn_data;
  6137. mg_call(c, MG_EV_OPEN, NULL);
  6138. mg_call(c, MG_EV_ACCEPT, NULL);
  6139. return c;
  6140. }
  6141. static bool read_conn(struct mg_connection *c, struct pkt *pkt) {
  6142. struct tcpstate *s = (struct tcpstate *) (c + 1);
  6143. if (pkt->tcp->flags & TH_FIN) {
  6144. s->ack = mg_htonl(pkt->tcp->seq) + 1, s->seq = mg_htonl(pkt->tcp->ack);
  6145. c->is_closing = 1;
  6146. } else if (pkt->pay.len == 0) {
  6147. } else if (c->recv.size - c->recv.len < pkt->pay.len &&
  6148. !mg_iobuf_resize(&c->recv, c->recv.len + pkt->pay.len)) {
  6149. mg_error(c, "oom");
  6150. } else if (mg_ntohl(pkt->tcp->seq) != s->ack) {
  6151. mg_error(c, "oob: %x %x", mg_ntohl(pkt->tcp->seq), s->ack);
  6152. } else {
  6153. s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
  6154. memcpy(&c->recv.buf[c->recv.len], pkt->pay.buf, pkt->pay.len);
  6155. c->recv.len += pkt->pay.len;
  6156. struct mg_str evd = mg_str_n((char *) pkt->pay.buf, pkt->pay.len);
  6157. mg_call(c, MG_EV_READ, &evd);
  6158. return true;
  6159. }
  6160. return false;
  6161. }
  6162. static void rx_tcp(struct mip_if *ifp, struct pkt *pkt) {
  6163. struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
  6164. #if 0
  6165. MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len));
  6166. #endif
  6167. if (c != NULL && c->is_connecting && pkt->tcp->flags & (TH_SYN | TH_ACK)) {
  6168. struct tcpstate *s = (struct tcpstate *) (c + 1);
  6169. s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1;
  6170. tx_tcp_pkt(ifp, pkt, TH_ACK, pkt->tcp->ack, NULL, 0);
  6171. c->is_connecting = 0; // Client connected
  6172. } else if (c != NULL && c->is_connecting) {
  6173. tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  6174. } else if (c != NULL) {
  6175. #if 0
  6176. MG_DEBUG(("%lu %d %lx:%hu -> %lx:%hu", c->id, (int) pkt->raw.len,
  6177. mg_ntohl(pkt->ip->src), mg_ntohs(pkt->tcp->sport),
  6178. mg_ntohl(pkt->ip->dst), mg_ntohs(pkt->tcp->dport)));
  6179. mg_hexdump(pkt->pay.buf, pkt->pay.len);
  6180. #endif
  6181. if(read_conn(c, pkt)) {
  6182. // Send ACK immediately, no piggyback yet
  6183. // TODO() Set a timer and send ACK if timer expires and no segment was sent ?
  6184. // (clear timer on segment sent)
  6185. struct tcpstate *s = (struct tcpstate *) (c + 1);
  6186. tx_tcp(ifp, c->rem.ip, TH_ACK, c->loc.port, c->rem.port, mg_htonl(s->seq),
  6187. mg_htonl(s->ack), NULL, 0);
  6188. }
  6189. } else if ((c = getpeer(ifp->mgr, pkt, true)) == NULL) {
  6190. tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  6191. } else if (pkt->tcp->flags & TH_SYN) {
  6192. // Use peer's source port as ISN, in order to recognise the handshake
  6193. uint32_t isn = mg_htonl((uint32_t) mg_ntohs(pkt->tcp->sport));
  6194. tx_tcp_pkt(ifp, pkt, TH_SYN | TH_ACK, isn, NULL, 0);
  6195. } else if (pkt->tcp->flags & TH_FIN) {
  6196. tx_tcp_pkt(ifp, pkt, TH_FIN | TH_ACK, pkt->tcp->ack, NULL, 0);
  6197. } else if (mg_htonl(pkt->tcp->ack) == mg_htons(pkt->tcp->sport) + 1U) {
  6198. accept_conn(c, pkt);
  6199. } else {
  6200. // MG_DEBUG(("dropped silently.."));
  6201. }
  6202. }
  6203. static void rx_ip(struct mip_if *ifp, struct pkt *pkt) {
  6204. // MG_DEBUG(("IP %d", (int) pkt->pay.len));
  6205. if (pkt->ip->proto == 1) {
  6206. pkt->icmp = (struct icmp *) (pkt->ip + 1);
  6207. if (pkt->pay.len < sizeof(*pkt->icmp)) return;
  6208. mkpay(pkt, pkt->icmp + 1);
  6209. rx_icmp(ifp, pkt);
  6210. } else if (pkt->ip->proto == 17) {
  6211. pkt->udp = (struct udp *) (pkt->ip + 1);
  6212. if (pkt->pay.len < sizeof(*pkt->udp)) return;
  6213. // MG_DEBUG((" UDP %u %u -> %u\n", len, mg_htons(udp->sport),
  6214. // mg_htons(udp->dport)));
  6215. mkpay(pkt, pkt->udp + 1);
  6216. if (pkt->udp->dport == mg_htons(68)) {
  6217. pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
  6218. mkpay(pkt, pkt->dhcp + 1);
  6219. rx_dhcp(ifp, pkt);
  6220. } else {
  6221. rx_udp(ifp, pkt);
  6222. }
  6223. } else if (pkt->ip->proto == 6) {
  6224. pkt->tcp = (struct tcp *) (pkt->ip + 1);
  6225. if (pkt->pay.len < sizeof(*pkt->tcp)) return;
  6226. mkpay(pkt, pkt->tcp + 1);
  6227. uint16_t iplen = mg_ntohs(pkt->ip->len);
  6228. uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
  6229. if (iplen >= off) pkt->pay.len = (size_t) (iplen - off);
  6230. rx_tcp(ifp, pkt);
  6231. }
  6232. }
  6233. static void rx_ip6(struct mip_if *ifp, struct pkt *pkt) {
  6234. // MG_DEBUG(("IP %d\n", (int) len));
  6235. if (pkt->ip6->proto == 1 || pkt->ip6->proto == 58) {
  6236. pkt->icmp = (struct icmp *) (pkt->ip6 + 1);
  6237. if (pkt->pay.len < sizeof(*pkt->icmp)) return;
  6238. mkpay(pkt, pkt->icmp + 1);
  6239. rx_icmp(ifp, pkt);
  6240. } else if (pkt->ip->proto == 17) {
  6241. pkt->udp = (struct udp *) (pkt->ip6 + 1);
  6242. if (pkt->pay.len < sizeof(*pkt->udp)) return;
  6243. // MG_DEBUG((" UDP %u %u -> %u\n", len, mg_htons(udp->sport),
  6244. // mg_htons(udp->dport)));
  6245. mkpay(pkt, pkt->udp + 1);
  6246. }
  6247. }
  6248. static void mip_rx(struct mip_if *ifp, void *buf, size_t len) {
  6249. const uint8_t broadcast[] = {255, 255, 255, 255, 255, 255};
  6250. struct pkt pkt = {.raw = {.buf = (uint8_t *) buf, .len = len}};
  6251. pkt.eth = (struct eth *) buf;
  6252. if (pkt.raw.len < sizeof(*pkt.eth)) return; // Truncated - runt?
  6253. if (memcmp(pkt.eth->dst, ifp->mac, sizeof(pkt.eth->dst)) != 0 &&
  6254. memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0) {
  6255. // Not for us. Drop silently
  6256. } else if (pkt.eth->type == mg_htons(0x806)) {
  6257. pkt.arp = (struct arp *) (pkt.eth + 1);
  6258. if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) return; // Truncated
  6259. rx_arp(ifp, &pkt);
  6260. } else if (pkt.eth->type == mg_htons(0x86dd)) {
  6261. pkt.ip6 = (struct ip6 *) (pkt.eth + 1);
  6262. if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip6)) return; // Truncated
  6263. if ((pkt.ip6->ver >> 4) != 0x6) return; // Not IP
  6264. mkpay(&pkt, pkt.ip6 + 1);
  6265. rx_ip6(ifp, &pkt);
  6266. } else if (pkt.eth->type == mg_htons(0x800)) {
  6267. pkt.ip = (struct ip *) (pkt.eth + 1);
  6268. if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) return; // Truncated
  6269. if ((pkt.ip->ver >> 4) != 4) return; // Not IP
  6270. mkpay(&pkt, pkt.ip + 1);
  6271. rx_ip(ifp, &pkt);
  6272. } else {
  6273. MG_DEBUG((" Unknown eth type %x\n", mg_htons(pkt.eth->type)));
  6274. }
  6275. }
  6276. static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
  6277. if (ifp == NULL || ifp->driver == NULL) return;
  6278. ifp->curtime = uptime_ms;
  6279. if (ifp->ip == 0 && uptime_ms > ifp->timer) {
  6280. tx_dhcp_discover(ifp); // If IP not configured, send DHCP
  6281. ifp->timer = uptime_ms + 1000; // with some interval
  6282. } else if (ifp->use_dhcp == false && uptime_ms > ifp->timer &&
  6283. arp_cache_find(ifp, ifp->gw) == NULL) {
  6284. arp_ask(ifp, ifp->gw); // If GW's MAC address in not in ARP cache
  6285. ifp->timer = uptime_ms + 1000; // send ARP who-has request
  6286. }
  6287. // Handle physical interface up/down status
  6288. if (ifp->driver->up) {
  6289. bool up = ifp->driver->up(ifp->driver_data);
  6290. bool current = ifp->state != MIP_STATE_DOWN;
  6291. if (up != current) {
  6292. ifp->state = up == false ? MIP_STATE_DOWN
  6293. : ifp->use_dhcp ? MIP_STATE_UP
  6294. : MIP_STATE_READY;
  6295. if (!up && ifp->use_dhcp) ifp->ip = 0;
  6296. onstatechange(ifp);
  6297. }
  6298. }
  6299. // Read data from the network
  6300. for (;;) {
  6301. size_t len = ifp->queue.len > 0 ? q_read(&ifp->queue, ifp->rx.buf)
  6302. : ifp->driver->rx(ifp->rx.buf, ifp->rx.len,
  6303. ifp->driver_data);
  6304. if (len == 0) break;
  6305. mip_rx(ifp, ifp->rx.buf, len);
  6306. }
  6307. }
  6308. // This function executes in interrupt context, thus it should copy data
  6309. // somewhere fast. Note that newlib's malloc is not thread safe, thus use
  6310. // our lock-free queue with preallocated buffer to copy data and return asap
  6311. static void on_rx(void *buf, size_t len, void *userdata) {
  6312. struct mip_if *ifp = (struct mip_if *) userdata;
  6313. if (!q_write(&ifp->queue, buf, len)) MG_ERROR(("dropped %d", (int) len));
  6314. }
  6315. void mip_init(struct mg_mgr *mgr, struct mip_cfg *ipcfg,
  6316. struct mip_driver *driver, void *driver_data) {
  6317. if (driver->init && !driver->init(ipcfg->mac, driver_data)) {
  6318. MG_ERROR(("driver init failed"));
  6319. } else {
  6320. size_t maxpktsize = 1500, qlen = driver->setrx ? 1024 * 16 : 0;
  6321. struct mip_if *ifp =
  6322. (struct mip_if *) calloc(1, sizeof(*ifp) + 2 * maxpktsize + qlen);
  6323. memcpy(ifp->mac, ipcfg->mac, sizeof(ifp->mac));
  6324. ifp->use_dhcp = ipcfg->ip == 0;
  6325. ifp->ip = ipcfg->ip, ifp->mask = ipcfg->mask, ifp->gw = ipcfg->gw;
  6326. ifp->rx.buf = (uint8_t *) (ifp + 1), ifp->rx.len = maxpktsize;
  6327. ifp->tx.buf = ifp->rx.buf + maxpktsize, ifp->tx.len = maxpktsize;
  6328. ifp->driver = driver;
  6329. ifp->driver_data = driver_data;
  6330. ifp->mgr = mgr;
  6331. ifp->queue.buf = ifp->tx.buf + maxpktsize;
  6332. ifp->queue.len = qlen;
  6333. if (driver->setrx) driver->setrx(on_rx, ifp);
  6334. mgr->priv = ifp;
  6335. mgr->extraconnsize = sizeof(struct tcpstate);
  6336. }
  6337. }
  6338. int mg_mkpipe(struct mg_mgr *m, mg_event_handler_t fn, void *d, bool udp) {
  6339. (void) m, (void) fn, (void) d, (void) udp;
  6340. MG_ERROR(("Not implemented"));
  6341. return -1;
  6342. }
  6343. #if 0
  6344. static uint16_t mkeport(void) {
  6345. uint16_t a = 0, b = mg_millis() & 0xffffU, c = MIP_ETHEMERAL_PORT;
  6346. mg_random(&a, sizeof(a));
  6347. c += (a ^ b) % (0xffffU - MIP_ETHEMERAL_PORT);
  6348. return c;
  6349. }
  6350. #endif
  6351. void mg_connect_resolved(struct mg_connection *c) {
  6352. struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
  6353. c->is_resolving = 0;
  6354. if (ifp->eport < MIP_ETHEMERAL_PORT) ifp->eport = MIP_ETHEMERAL_PORT;
  6355. c->loc.ip = ifp->ip;
  6356. c->loc.port = mg_htons(ifp->eport++);
  6357. MG_DEBUG(("%lu %08lx.%hu->%08lx.%hu", c->id, mg_ntohl(c->loc.ip),
  6358. mg_ntohs(c->loc.port), mg_ntohl(c->rem.ip), mg_ntohs(c->rem.port)));
  6359. mg_call(c, MG_EV_RESOLVE, NULL);
  6360. if (c->is_udp) {
  6361. mg_call(c, MG_EV_CONNECT, NULL);
  6362. } else {
  6363. uint32_t isn = mg_htonl((uint32_t) mg_ntohs(c->loc.port));
  6364. tx_tcp(ifp, c->rem.ip, TH_SYN, c->loc.port, c->rem.port, isn, 0, NULL, 0);
  6365. c->is_connecting = 1;
  6366. }
  6367. }
  6368. bool mg_open_listener(struct mg_connection *c, const char *url) {
  6369. c->loc.port = mg_htons(mg_url_port(url));
  6370. return true;
  6371. }
  6372. static void write_conn(struct mg_connection *c) {
  6373. struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
  6374. struct tcpstate *s = (struct tcpstate *) (c + 1);
  6375. size_t sent, n = c->send.len, hdrlen = 14 + 24 /*max IP*/ + 60 /*max TCP*/;
  6376. if (n + hdrlen > ifp->tx.len) n = ifp->tx.len - hdrlen;
  6377. sent = tx_tcp(ifp, c->rem.ip, TH_PUSH | TH_ACK, c->loc.port, c->rem.port,
  6378. mg_htonl(s->seq), mg_htonl(s->ack), c->send.buf, n);
  6379. if (sent > 0) {
  6380. mg_iobuf_del(&c->send, 0, n);
  6381. s->seq += (uint32_t) n;
  6382. mg_call(c, MG_EV_WRITE, &n);
  6383. }
  6384. }
  6385. static void fin_conn(struct mg_connection *c) {
  6386. struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
  6387. struct tcpstate *s = (struct tcpstate *) (c + 1);
  6388. tx_tcp(ifp, c->rem.ip, TH_FIN | TH_ACK, c->loc.port, c->rem.port,
  6389. mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  6390. }
  6391. static bool can_write(struct mg_connection *c) {
  6392. return c->is_connecting == 0 && c->is_resolving == 0 && c->send.len > 0;
  6393. }
  6394. void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
  6395. struct mg_connection *c, *tmp;
  6396. uint64_t now = mg_millis();
  6397. mip_poll((struct mip_if *) mgr->priv, now);
  6398. mg_timer_poll(&mgr->timers, now);
  6399. for (c = mgr->conns; c != NULL; c = tmp) {
  6400. tmp = c->next;
  6401. if (can_write(c)) write_conn(c);
  6402. if (c->is_draining && c->send.len == 0) c->is_closing = 1;
  6403. if (c->is_closing) {
  6404. if (c->is_udp == false && c->is_listening == false) fin_conn(c);
  6405. mg_close_conn(c);
  6406. }
  6407. }
  6408. (void) ms;
  6409. }
  6410. bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
  6411. struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
  6412. bool res = false;
  6413. if (ifp->ip == 0) {
  6414. mg_error(c, "net down");
  6415. } else if (c->is_udp) {
  6416. tx_udp(ifp, ifp->ip, c->loc.port, c->rem.ip, c->rem.port, buf, len);
  6417. res = true;
  6418. } else {
  6419. // tx_tdp(ifp, ifp->ip, c->loc.port, c->rem.ip, c->rem.port, buf, len);
  6420. return mg_iobuf_add(&c->send, c->send.len, buf, len);
  6421. }
  6422. return res;
  6423. }
  6424. #endif // MG_ENABLE_MIP