mongoose.c 273 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137
  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-only 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 == NULL ? NULL : src + n; // Cannot add to NULL
  84. int len = 0;
  85. while (src != NULL && 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. dm.addr.port = d->c->rem.port; // Save port
  243. d->c->rem = dm.addr; // Copy resolved address
  244. MG_DEBUG(
  245. ("%lu %s is %M", d->c->id, dm.name, mg_print_ip, &d->c->rem));
  246. mg_connect_resolved(d->c);
  247. #if MG_ENABLE_IPV6
  248. } else if (dm.addr.is_ip6 == false && dm.name[0] != '\0' &&
  249. c->mgr->use_dns6 == false) {
  250. struct mg_str x = mg_str(dm.name);
  251. mg_sendnsreq(d->c, &x, c->mgr->dnstimeout, &c->mgr->dns6, true);
  252. #endif
  253. } else {
  254. mg_error(d->c, "%s DNS lookup failed", dm.name);
  255. }
  256. } else {
  257. MG_ERROR(("%lu already resolved", d->c->id));
  258. }
  259. mg_dns_free(c, d);
  260. resolved = 1;
  261. }
  262. }
  263. if (!resolved) MG_ERROR(("stray DNS reply"));
  264. c->recv.len = 0;
  265. } else if (ev == MG_EV_CLOSE) {
  266. for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
  267. d = tmp) {
  268. tmp = d->next;
  269. mg_error(d->c, "DNS error");
  270. mg_dns_free(c, d);
  271. }
  272. }
  273. (void) fn_data;
  274. }
  275. static bool mg_dns_send(struct mg_connection *c, const struct mg_str *name,
  276. uint16_t txnid, bool ipv6) {
  277. struct {
  278. struct mg_dns_header header;
  279. uint8_t data[256];
  280. } pkt;
  281. size_t i, n;
  282. memset(&pkt, 0, sizeof(pkt));
  283. pkt.header.txnid = mg_htons(txnid);
  284. pkt.header.flags = mg_htons(0x100);
  285. pkt.header.num_questions = mg_htons(1);
  286. for (i = n = 0; i < sizeof(pkt.data) - 5; i++) {
  287. if (name->ptr[i] == '.' || i >= name->len) {
  288. pkt.data[n] = (uint8_t) (i - n);
  289. memcpy(&pkt.data[n + 1], name->ptr + n, i - n);
  290. n = i + 1;
  291. }
  292. if (i >= name->len) break;
  293. }
  294. memcpy(&pkt.data[n], "\x00\x00\x01\x00\x01", 5); // A query
  295. n += 5;
  296. if (ipv6) pkt.data[n - 3] = 0x1c; // AAAA query
  297. // memcpy(&pkt.data[n], "\xc0\x0c\x00\x1c\x00\x01", 6); // AAAA query
  298. // n += 6;
  299. return mg_send(c, &pkt, sizeof(pkt.header) + n);
  300. }
  301. static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
  302. struct mg_dns *dnsc, bool ipv6) {
  303. struct dns_data *d = NULL;
  304. if (dnsc->url == NULL) {
  305. mg_error(c, "DNS server URL is NULL. Call mg_mgr_init()");
  306. } else if (dnsc->c == NULL) {
  307. dnsc->c = mg_connect(c->mgr, dnsc->url, NULL, NULL);
  308. if (dnsc->c != NULL) {
  309. dnsc->c->pfn = dns_cb;
  310. // dnsc->c->is_hexdumping = 1;
  311. }
  312. }
  313. if (dnsc->c == NULL) {
  314. mg_error(c, "resolver");
  315. } else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) {
  316. mg_error(c, "resolve OOM");
  317. } else {
  318. struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests;
  319. d->txnid = reqs ? (uint16_t) (reqs->txnid + 1) : 1;
  320. d->next = (struct dns_data *) c->mgr->active_dns_requests;
  321. c->mgr->active_dns_requests = d;
  322. d->expire = mg_millis() + (uint64_t) ms;
  323. d->c = c;
  324. c->is_resolving = 1;
  325. MG_VERBOSE(("%lu resolving %.*s @ %s, txnid %hu", c->id, (int) name->len,
  326. name->ptr, dnsc->url, d->txnid));
  327. if (!mg_dns_send(dnsc->c, name, d->txnid, ipv6)) {
  328. mg_error(dnsc->c, "DNS send");
  329. }
  330. }
  331. }
  332. void mg_resolve(struct mg_connection *c, const char *url) {
  333. struct mg_str host = mg_url_host(url);
  334. c->rem.port = mg_htons(mg_url_port(url));
  335. if (mg_aton(host, &c->rem)) {
  336. // host is an IP address, do not fire name resolution
  337. mg_connect_resolved(c);
  338. } else {
  339. // host is not an IP, send DNS resolution request
  340. struct mg_dns *dns = c->mgr->use_dns6 ? &c->mgr->dns6 : &c->mgr->dns4;
  341. mg_sendnsreq(c, &host, c->mgr->dnstimeout, dns, c->mgr->use_dns6);
  342. }
  343. }
  344. #ifdef MG_ENABLE_LINES
  345. #line 1 "src/event.c"
  346. #endif
  347. void mg_call(struct mg_connection *c, int ev, void *ev_data) {
  348. // Run user-defined handler first, in order to give it an ability
  349. // to intercept processing (e.g. clean input buffer) before the
  350. // protocol handler kicks in
  351. if (c->fn != NULL) c->fn(c, ev, ev_data, c->fn_data);
  352. if (c->pfn != NULL) c->pfn(c, ev, ev_data, c->pfn_data);
  353. }
  354. void mg_error(struct mg_connection *c, const char *fmt, ...) {
  355. char buf[64];
  356. va_list ap;
  357. va_start(ap, fmt);
  358. mg_vsnprintf(buf, sizeof(buf), fmt, &ap);
  359. va_end(ap);
  360. MG_ERROR(("%lu %p %s", c->id, c->fd, buf));
  361. c->is_closing = 1; // Set is_closing before sending MG_EV_CALL
  362. mg_call(c, MG_EV_ERROR, buf); // Let user handler to override it
  363. }
  364. #ifdef MG_ENABLE_LINES
  365. #line 1 "src/fmt.c"
  366. #endif
  367. static bool is_digit(int c) {
  368. return c >= '0' && c <= '9';
  369. }
  370. static int addexp(char *buf, int e, int sign) {
  371. int n = 0;
  372. buf[n++] = 'e';
  373. buf[n++] = (char) sign;
  374. if (e > 400) return 0;
  375. if (e < 10) buf[n++] = '0';
  376. if (e >= 100) buf[n++] = (char) (e / 100 + '0'), e -= 100 * (e / 100);
  377. if (e >= 10) buf[n++] = (char) (e / 10 + '0'), e -= 10 * (e / 10);
  378. buf[n++] = (char) (e + '0');
  379. return n;
  380. }
  381. static int xisinf(double x) {
  382. union {
  383. double f;
  384. uint64_t u;
  385. } ieee754 = {x};
  386. return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
  387. ((unsigned) ieee754.u == 0);
  388. }
  389. static int xisnan(double x) {
  390. union {
  391. double f;
  392. uint64_t u;
  393. } ieee754 = {x};
  394. return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
  395. ((unsigned) ieee754.u != 0) >
  396. 0x7ff00000;
  397. }
  398. static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) {
  399. char buf[40];
  400. int i, s = 0, n = 0, e = 0;
  401. double t, mul, saved;
  402. if (d == 0.0) return mg_snprintf(dst, dstlen, "%s", "0");
  403. if (xisinf(d)) return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf");
  404. if (xisnan(d)) return mg_snprintf(dst, dstlen, "%s", "nan");
  405. if (d < 0.0) d = -d, buf[s++] = '-';
  406. // Round
  407. saved = d;
  408. mul = 1.0;
  409. while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0;
  410. while (d <= 1.0 && d / mul <= 1.0) mul /= 10.0;
  411. for (i = 0, t = mul * 5; i < width; i++) t /= 10.0;
  412. d += t;
  413. // Calculate exponent, and 'mul' for scientific representation
  414. mul = 1.0;
  415. while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0, e++;
  416. while (d < 1.0 && d / mul < 1.0) mul /= 10.0, e--;
  417. // printf(" --> %g %d %g %g\n", saved, e, t, mul);
  418. if (e >= width && width > 1) {
  419. n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
  420. // printf(" --> %.*g %d [%.*s]\n", 10, d / t, e, n, buf);
  421. n += addexp(buf + s + n, e, '+');
  422. return mg_snprintf(dst, dstlen, "%.*s", n, buf);
  423. } else if (e <= -width && width > 1) {
  424. n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
  425. // printf(" --> %.*g %d [%.*s]\n", 10, d / mul, e, n, buf);
  426. n += addexp(buf + s + n, -e, '-');
  427. return mg_snprintf(dst, dstlen, "%.*s", n, buf);
  428. } else {
  429. for (i = 0, t = mul; t >= 1.0 && s + n < (int) sizeof(buf); i++) {
  430. int ch = (int) (d / t);
  431. if (n > 0 || ch > 0) buf[s + n++] = (char) (ch + '0');
  432. d -= ch * t;
  433. t /= 10.0;
  434. }
  435. // printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf);
  436. if (n == 0) buf[s++] = '0';
  437. while (t >= 1.0 && n + s < (int) sizeof(buf)) buf[n++] = '0', t /= 10.0;
  438. if (s + n < (int) sizeof(buf)) buf[n + s++] = '.';
  439. // printf(" 1--> [%g] -> [%.*s]\n", saved, s + n, buf);
  440. for (i = 0, t = 0.1; s + n < (int) sizeof(buf) && n < width; i++) {
  441. int ch = (int) (d / t);
  442. buf[s + n++] = (char) (ch + '0');
  443. d -= ch * t;
  444. t /= 10.0;
  445. }
  446. }
  447. while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes
  448. if (n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
  449. n += s;
  450. if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1;
  451. buf[n] = '\0';
  452. return mg_snprintf(dst, dstlen, "%s", buf);
  453. }
  454. static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
  455. const char *letters = "0123456789abcdef";
  456. uint64_t v = (uint64_t) val;
  457. size_t s = 0, n, i;
  458. if (is_signed && val < 0) buf[s++] = '-', v = (uint64_t) (-val);
  459. // This loop prints a number in reverse order. I guess this is because we
  460. // write numbers from right to left: least significant digit comes last.
  461. // Maybe because we use Arabic numbers, and Arabs write RTL?
  462. if (is_hex) {
  463. for (n = 0; v; v >>= 4) buf[s + n++] = letters[v & 15];
  464. } else {
  465. for (n = 0; v; v /= 10) buf[s + n++] = letters[v % 10];
  466. }
  467. // Reverse a string
  468. for (i = 0; i < n / 2; i++) {
  469. char t = buf[s + i];
  470. buf[s + i] = buf[s + n - i - 1], buf[s + n - i - 1] = t;
  471. }
  472. if (val == 0) buf[n++] = '0'; // Handle special case
  473. return n + s;
  474. }
  475. static size_t scpy(void (*out)(char, void *), void *ptr, char *buf,
  476. size_t len) {
  477. size_t i = 0;
  478. while (i < len && buf[i] != '\0') out(buf[i++], ptr);
  479. return i;
  480. }
  481. size_t mg_xprintf(void (*out)(char, void *), void *ptr, const char *fmt, ...) {
  482. size_t len = 0;
  483. va_list ap;
  484. va_start(ap, fmt);
  485. len = mg_vxprintf(out, ptr, fmt, &ap);
  486. va_end(ap);
  487. return len;
  488. }
  489. size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
  490. va_list *ap) {
  491. size_t i = 0, n = 0;
  492. while (fmt[i] != '\0') {
  493. if (fmt[i] == '%') {
  494. size_t j, k, x = 0, is_long = 0, w = 0 /* width */, pr = ~0U /* prec */;
  495. char pad = ' ', minus = 0, c = fmt[++i];
  496. if (c == '#') x++, c = fmt[++i];
  497. if (c == '-') minus++, c = fmt[++i];
  498. if (c == '0') pad = '0', c = fmt[++i];
  499. while (is_digit(c)) w *= 10, w += (size_t) (c - '0'), c = fmt[++i];
  500. if (c == '.') {
  501. c = fmt[++i];
  502. if (c == '*') {
  503. pr = (size_t) va_arg(*ap, int);
  504. c = fmt[++i];
  505. } else {
  506. pr = 0;
  507. while (is_digit(c)) pr *= 10, pr += (size_t) (c - '0'), c = fmt[++i];
  508. }
  509. }
  510. while (c == 'h') c = fmt[++i]; // Treat h and hh as int
  511. if (c == 'l') {
  512. is_long++, c = fmt[++i];
  513. if (c == 'l') is_long++, c = fmt[++i];
  514. }
  515. if (c == 'p') x = 1, is_long = 1;
  516. if (c == 'd' || c == 'u' || c == 'x' || c == 'X' || c == 'p' ||
  517. c == 'g' || c == 'f') {
  518. bool s = (c == 'd'), h = (c == 'x' || c == 'X' || c == 'p');
  519. char tmp[40];
  520. size_t xl = x ? 2 : 0;
  521. if (c == 'g' || c == 'f') {
  522. double v = va_arg(*ap, double);
  523. if (pr == ~0U) pr = 6;
  524. k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr, c == 'g');
  525. } else if (is_long == 2) {
  526. int64_t v = va_arg(*ap, int64_t);
  527. k = mg_lld(tmp, v, s, h);
  528. } else if (is_long == 1) {
  529. long v = va_arg(*ap, long);
  530. k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned long) v, s, h);
  531. } else {
  532. int v = va_arg(*ap, int);
  533. k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned) v, s, h);
  534. }
  535. for (j = 0; j < xl && w > 0; j++) w--;
  536. for (j = 0; pad == ' ' && !minus && k < w && j + k < w; j++)
  537. n += scpy(out, param, &pad, 1);
  538. n += scpy(out, param, (char *) "0x", xl);
  539. for (j = 0; pad == '0' && k < w && j + k < w; j++)
  540. n += scpy(out, param, &pad, 1);
  541. n += scpy(out, param, tmp, k);
  542. for (j = 0; pad == ' ' && minus && k < w && j + k < w; j++)
  543. n += scpy(out, param, &pad, 1);
  544. } else if (c == 'm' || c == 'M') {
  545. mg_pm_t f = va_arg(*ap, mg_pm_t);
  546. if (c == 'm') out('"', param);
  547. n += f(out, param, ap);
  548. if (c == 'm') n += 2, out('"', param);
  549. } else if (c == 'c') {
  550. int ch = va_arg(*ap, int);
  551. out((char) ch, param);
  552. n++;
  553. } else if (c == 's') {
  554. char *p = va_arg(*ap, char *);
  555. if (pr == ~0U) pr = p == NULL ? 0 : strlen(p);
  556. for (j = 0; !minus && pr < w && j + pr < w; j++)
  557. n += scpy(out, param, &pad, 1);
  558. n += scpy(out, param, p, pr);
  559. for (j = 0; minus && pr < w && j + pr < w; j++)
  560. n += scpy(out, param, &pad, 1);
  561. } else if (c == '%') {
  562. out('%', param);
  563. n++;
  564. } else {
  565. out('%', param);
  566. out(c, param);
  567. n += 2;
  568. }
  569. i++;
  570. } else {
  571. out(fmt[i], param), n++, i++;
  572. }
  573. }
  574. return n;
  575. }
  576. #ifdef MG_ENABLE_LINES
  577. #line 1 "src/fs.c"
  578. #endif
  579. struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) {
  580. struct mg_fd *fd = (struct mg_fd *) calloc(1, sizeof(*fd));
  581. if (fd != NULL) {
  582. fd->fd = fs->op(path, flags);
  583. fd->fs = fs;
  584. if (fd->fd == NULL) {
  585. free(fd);
  586. fd = NULL;
  587. }
  588. }
  589. return fd;
  590. }
  591. void mg_fs_close(struct mg_fd *fd) {
  592. if (fd != NULL) {
  593. fd->fs->cl(fd->fd);
  594. free(fd);
  595. }
  596. }
  597. char *mg_file_read(struct mg_fs *fs, const char *path, size_t *sizep) {
  598. struct mg_fd *fd;
  599. char *data = NULL;
  600. size_t size = 0;
  601. fs->st(path, &size, NULL);
  602. if ((fd = mg_fs_open(fs, path, MG_FS_READ)) != NULL) {
  603. data = (char *) calloc(1, size + 1);
  604. if (data != NULL) {
  605. if (fs->rd(fd->fd, data, size) != size) {
  606. free(data);
  607. data = NULL;
  608. } else {
  609. data[size] = '\0';
  610. if (sizep != NULL) *sizep = size;
  611. }
  612. }
  613. mg_fs_close(fd);
  614. }
  615. return data;
  616. }
  617. bool mg_file_write(struct mg_fs *fs, const char *path, const void *buf,
  618. size_t len) {
  619. bool result = false;
  620. struct mg_fd *fd;
  621. char tmp[MG_PATH_MAX];
  622. mg_snprintf(tmp, sizeof(tmp), "%s..%d", path, rand());
  623. if ((fd = mg_fs_open(fs, tmp, MG_FS_WRITE)) != NULL) {
  624. result = fs->wr(fd->fd, buf, len) == len;
  625. mg_fs_close(fd);
  626. if (result) {
  627. fs->rm(path);
  628. fs->mv(tmp, path);
  629. } else {
  630. fs->rm(tmp);
  631. }
  632. }
  633. return result;
  634. }
  635. bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...) {
  636. va_list ap;
  637. char *data;
  638. bool result = false;
  639. va_start(ap, fmt);
  640. data = mg_vmprintf(fmt, &ap);
  641. va_end(ap);
  642. result = mg_file_write(fs, path, data, strlen(data));
  643. free(data);
  644. return result;
  645. }
  646. #ifdef MG_ENABLE_LINES
  647. #line 1 "src/fs_fat.c"
  648. #endif
  649. #if MG_ENABLE_FATFS
  650. #include <ff.h>
  651. static int mg_days_from_epoch(int y, int m, int d) {
  652. y -= m <= 2;
  653. int era = y / 400;
  654. int yoe = y - era * 400;
  655. int doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1;
  656. int doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
  657. return era * 146097 + doe - 719468;
  658. }
  659. static time_t mg_timegm(const struct tm *t) {
  660. int year = t->tm_year + 1900;
  661. int month = t->tm_mon; // 0-11
  662. if (month > 11) {
  663. year += month / 12;
  664. month %= 12;
  665. } else if (month < 0) {
  666. int years_diff = (11 - month) / 12;
  667. year -= years_diff;
  668. month += 12 * years_diff;
  669. }
  670. int x = mg_days_from_epoch(year, month + 1, t->tm_mday);
  671. return 60 * (60 * (24L * x + t->tm_hour) + t->tm_min) + t->tm_sec;
  672. }
  673. static time_t ff_time_to_epoch(uint16_t fdate, uint16_t ftime) {
  674. struct tm tm;
  675. memset(&tm, 0, sizeof(struct tm));
  676. tm.tm_sec = (ftime << 1) & 0x3e;
  677. tm.tm_min = ((ftime >> 5) & 0x3f);
  678. tm.tm_hour = ((ftime >> 11) & 0x1f);
  679. tm.tm_mday = (fdate & 0x1f);
  680. tm.tm_mon = ((fdate >> 5) & 0x0f) - 1;
  681. tm.tm_year = ((fdate >> 9) & 0x7f) + 80;
  682. return mg_timegm(&tm);
  683. }
  684. static int ff_stat(const char *path, size_t *size, time_t *mtime) {
  685. FILINFO fi;
  686. if (path[0] == '\0') {
  687. if (size) *size = 0;
  688. if (mtime) *mtime = 0;
  689. return MG_FS_DIR;
  690. } else if (f_stat(path, &fi) == 0) {
  691. if (size) *size = (size_t) fi.fsize;
  692. if (mtime) *mtime = ff_time_to_epoch(fi.fdate, fi.ftime);
  693. return MG_FS_READ | MG_FS_WRITE | ((fi.fattrib & AM_DIR) ? MG_FS_DIR : 0);
  694. } else {
  695. return 0;
  696. }
  697. }
  698. static void ff_list(const char *dir, void (*fn)(const char *, void *),
  699. void *userdata) {
  700. DIR d;
  701. FILINFO fi;
  702. if (f_opendir(&d, dir) == FR_OK) {
  703. while (f_readdir(&d, &fi) == FR_OK && fi.fname[0] != '\0') {
  704. if (!strcmp(fi.fname, ".") || !strcmp(fi.fname, "..")) continue;
  705. fn(fi.fname, userdata);
  706. }
  707. f_closedir(&d);
  708. }
  709. }
  710. static void *ff_open(const char *path, int flags) {
  711. FIL f;
  712. unsigned char mode = FA_READ;
  713. if (flags & MG_FS_WRITE) mode |= FA_WRITE | FA_OPEN_ALWAYS | FA_OPEN_APPEND;
  714. if (f_open(&f, path, mode) == 0) {
  715. FIL *fp = calloc(1, sizeof(*fp));
  716. memcpy(fp, &f, sizeof(*fp));
  717. return fp;
  718. } else {
  719. return NULL;
  720. }
  721. }
  722. static void ff_close(void *fp) {
  723. if (fp != NULL) {
  724. f_close((FIL *) fp);
  725. free(fp);
  726. }
  727. }
  728. static size_t ff_read(void *fp, void *buf, size_t len) {
  729. UINT n = 0, misalign = ((size_t) buf) & 3;
  730. if (misalign) {
  731. char aligned[4];
  732. f_read((FIL *) fp, aligned, len > misalign ? misalign : len, &n);
  733. memcpy(buf, aligned, n);
  734. } else {
  735. f_read((FIL *) fp, buf, len, &n);
  736. }
  737. return n;
  738. }
  739. static size_t ff_write(void *fp, const void *buf, size_t len) {
  740. UINT n = 0;
  741. return f_write((FIL *) fp, (char *) buf, len, &n) == FR_OK ? n : 0;
  742. }
  743. static size_t ff_seek(void *fp, size_t offset) {
  744. f_lseek((FIL *) fp, offset);
  745. return offset;
  746. }
  747. static bool ff_rename(const char *from, const char *to) {
  748. return f_rename(from, to) == FR_OK;
  749. }
  750. static bool ff_remove(const char *path) {
  751. return f_unlink(path) == FR_OK;
  752. }
  753. static bool ff_mkdir(const char *path) {
  754. return f_mkdir(path) == FR_OK;
  755. }
  756. struct mg_fs mg_fs_fat = {ff_stat, ff_list, ff_open, ff_close, ff_read,
  757. ff_write, ff_seek, ff_rename, ff_remove, ff_mkdir};
  758. #endif
  759. #ifdef MG_ENABLE_LINES
  760. #line 1 "src/fs_packed.c"
  761. #endif
  762. struct packed_file {
  763. const char *data;
  764. size_t size;
  765. size_t pos;
  766. };
  767. const char *mg_unpack(const char *path, size_t *size, time_t *mtime);
  768. const char *mg_unlist(size_t no);
  769. #if MG_ENABLE_PACKED_FS
  770. #else
  771. const char *mg_unpack(const char *path, size_t *size, time_t *mtime) {
  772. (void) path, (void) size, (void) mtime;
  773. return NULL;
  774. }
  775. const char *mg_unlist(size_t no) {
  776. (void) no;
  777. return NULL;
  778. }
  779. #endif
  780. static int is_dir_prefix(const char *prefix, size_t n, const char *path) {
  781. // MG_INFO(("[%.*s] [%s] %c", (int) n, prefix, path, path[n]));
  782. return n < strlen(path) && strncmp(prefix, path, n) == 0 &&
  783. (n == 0 || path[n] == '/' || path[n - 1] == '/');
  784. }
  785. static int packed_stat(const char *path, size_t *size, time_t *mtime) {
  786. const char *p;
  787. size_t i, n = strlen(path);
  788. if (mg_unpack(path, size, mtime)) return MG_FS_READ; // Regular file
  789. // Scan all files. If `path` is a dir prefix for any of them, it's a dir
  790. for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
  791. if (is_dir_prefix(path, n, p)) return MG_FS_DIR;
  792. }
  793. return 0;
  794. }
  795. static void packed_list(const char *dir, void (*fn)(const char *, void *),
  796. void *userdata) {
  797. char buf[MG_PATH_MAX], tmp[sizeof(buf)];
  798. const char *path, *begin, *end;
  799. size_t i, n = strlen(dir);
  800. tmp[0] = '\0'; // Previously listed entry
  801. for (i = 0; (path = mg_unlist(i)) != NULL; i++) {
  802. if (!is_dir_prefix(dir, n, path)) continue;
  803. begin = &path[n + 1];
  804. end = strchr(begin, '/');
  805. if (end == NULL) end = begin + strlen(begin);
  806. mg_snprintf(buf, sizeof(buf), "%.*s", (int) (end - begin), begin);
  807. buf[sizeof(buf) - 1] = '\0';
  808. // If this entry has been already listed, skip
  809. // NOTE: we're assuming that file list is sorted alphabetically
  810. if (strcmp(buf, tmp) == 0) continue;
  811. fn(buf, userdata); // Not yet listed, call user function
  812. strcpy(tmp, buf); // And save this entry as listed
  813. }
  814. }
  815. static void *packed_open(const char *path, int flags) {
  816. size_t size = 0;
  817. const char *data = mg_unpack(path, &size, NULL);
  818. struct packed_file *fp = NULL;
  819. if (data == NULL) return NULL;
  820. if (flags & MG_FS_WRITE) return NULL;
  821. fp = (struct packed_file *) calloc(1, sizeof(*fp));
  822. fp->size = size;
  823. fp->data = data;
  824. return (void *) fp;
  825. }
  826. static void packed_close(void *fp) {
  827. if (fp != NULL) free(fp);
  828. }
  829. static size_t packed_read(void *fd, void *buf, size_t len) {
  830. struct packed_file *fp = (struct packed_file *) fd;
  831. if (fp->pos + len > fp->size) len = fp->size - fp->pos;
  832. memcpy(buf, &fp->data[fp->pos], len);
  833. fp->pos += len;
  834. return len;
  835. }
  836. static size_t packed_write(void *fd, const void *buf, size_t len) {
  837. (void) fd, (void) buf, (void) len;
  838. return 0;
  839. }
  840. static size_t packed_seek(void *fd, size_t offset) {
  841. struct packed_file *fp = (struct packed_file *) fd;
  842. fp->pos = offset;
  843. if (fp->pos > fp->size) fp->pos = fp->size;
  844. return fp->pos;
  845. }
  846. static bool packed_rename(const char *from, const char *to) {
  847. (void) from, (void) to;
  848. return false;
  849. }
  850. static bool packed_remove(const char *path) {
  851. (void) path;
  852. return false;
  853. }
  854. static bool packed_mkdir(const char *path) {
  855. (void) path;
  856. return false;
  857. }
  858. struct mg_fs mg_fs_packed = {
  859. packed_stat, packed_list, packed_open, packed_close, packed_read,
  860. packed_write, packed_seek, packed_rename, packed_remove, packed_mkdir};
  861. #ifdef MG_ENABLE_LINES
  862. #line 1 "src/fs_posix.c"
  863. #endif
  864. #if MG_ENABLE_FILE
  865. #ifndef MG_STAT_STRUCT
  866. #define MG_STAT_STRUCT stat
  867. #endif
  868. #ifndef MG_STAT_FUNC
  869. #define MG_STAT_FUNC stat
  870. #endif
  871. static int p_stat(const char *path, size_t *size, time_t *mtime) {
  872. #if !defined(S_ISDIR)
  873. MG_ERROR(("stat() API is not supported. %p %p %p", path, size, mtime));
  874. return 0;
  875. #else
  876. #if MG_ARCH == MG_ARCH_WIN32
  877. struct _stati64 st;
  878. wchar_t tmp[MG_PATH_MAX];
  879. MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
  880. if (_wstati64(tmp, &st) != 0) return 0;
  881. // If path is a symlink, windows reports 0 in st.st_size.
  882. // Get a real file size by opening it and jumping to the end
  883. if (st.st_size == 0 && (st.st_mode & _S_IFREG)) {
  884. FILE *fp = _wfopen(tmp, L"rb");
  885. if (fp != NULL) {
  886. fseek(fp, 0, SEEK_END);
  887. if (ftell(fp) > 0) st.st_size = ftell(fp); // Use _ftelli64 on win10+
  888. fclose(fp);
  889. }
  890. }
  891. #else
  892. struct MG_STAT_STRUCT st;
  893. if (MG_STAT_FUNC(path, &st) != 0) return 0;
  894. #endif
  895. if (size) *size = (size_t) st.st_size;
  896. if (mtime) *mtime = st.st_mtime;
  897. return MG_FS_READ | MG_FS_WRITE | (S_ISDIR(st.st_mode) ? MG_FS_DIR : 0);
  898. #endif
  899. }
  900. #if MG_ARCH == MG_ARCH_WIN32
  901. struct dirent {
  902. char d_name[MAX_PATH];
  903. };
  904. typedef struct win32_dir {
  905. HANDLE handle;
  906. WIN32_FIND_DATAW info;
  907. struct dirent result;
  908. } DIR;
  909. int gettimeofday(struct timeval *tv, void *tz) {
  910. FILETIME ft;
  911. unsigned __int64 tmpres = 0;
  912. if (tv != NULL) {
  913. GetSystemTimeAsFileTime(&ft);
  914. tmpres |= ft.dwHighDateTime;
  915. tmpres <<= 32;
  916. tmpres |= ft.dwLowDateTime;
  917. tmpres /= 10; // convert into microseconds
  918. tmpres -= (int64_t) 11644473600000000;
  919. tv->tv_sec = (long) (tmpres / 1000000UL);
  920. tv->tv_usec = (long) (tmpres % 1000000UL);
  921. }
  922. (void) tz;
  923. return 0;
  924. }
  925. static int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
  926. int ret;
  927. char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
  928. strncpy(buf, path, sizeof(buf));
  929. buf[sizeof(buf) - 1] = '\0';
  930. // Trim trailing slashes. Leave backslash for paths like "X:\"
  931. p = buf + strlen(buf) - 1;
  932. while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
  933. memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
  934. ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
  935. // Convert back to Unicode. If doubly-converted string does not match the
  936. // original, something is fishy, reject.
  937. WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
  938. NULL, NULL);
  939. if (strcmp(buf, buf2) != 0) {
  940. wbuf[0] = L'\0';
  941. ret = 0;
  942. }
  943. return ret;
  944. }
  945. DIR *opendir(const char *name) {
  946. DIR *d = NULL;
  947. wchar_t wpath[MAX_PATH];
  948. DWORD attrs;
  949. if (name == NULL) {
  950. SetLastError(ERROR_BAD_ARGUMENTS);
  951. } else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) {
  952. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  953. } else {
  954. to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0]));
  955. attrs = GetFileAttributesW(wpath);
  956. if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
  957. (void) wcscat(wpath, L"\\*");
  958. d->handle = FindFirstFileW(wpath, &d->info);
  959. d->result.d_name[0] = '\0';
  960. } else {
  961. free(d);
  962. d = NULL;
  963. }
  964. }
  965. return d;
  966. }
  967. int closedir(DIR *d) {
  968. int result = 0;
  969. if (d != NULL) {
  970. if (d->handle != INVALID_HANDLE_VALUE)
  971. result = FindClose(d->handle) ? 0 : -1;
  972. free(d);
  973. } else {
  974. result = -1;
  975. SetLastError(ERROR_BAD_ARGUMENTS);
  976. }
  977. return result;
  978. }
  979. struct dirent *readdir(DIR *d) {
  980. struct dirent *result = NULL;
  981. if (d != NULL) {
  982. memset(&d->result, 0, sizeof(d->result));
  983. if (d->handle != INVALID_HANDLE_VALUE) {
  984. result = &d->result;
  985. WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name,
  986. sizeof(result->d_name), NULL, NULL);
  987. if (!FindNextFileW(d->handle, &d->info)) {
  988. FindClose(d->handle);
  989. d->handle = INVALID_HANDLE_VALUE;
  990. }
  991. } else {
  992. SetLastError(ERROR_FILE_NOT_FOUND);
  993. }
  994. } else {
  995. SetLastError(ERROR_BAD_ARGUMENTS);
  996. }
  997. return result;
  998. }
  999. #endif
  1000. static void p_list(const char *dir, void (*fn)(const char *, void *),
  1001. void *userdata) {
  1002. #if MG_ENABLE_DIRLIST
  1003. struct dirent *dp;
  1004. DIR *dirp;
  1005. if ((dirp = (opendir(dir))) == NULL) return;
  1006. while ((dp = readdir(dirp)) != NULL) {
  1007. if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
  1008. fn(dp->d_name, userdata);
  1009. }
  1010. closedir(dirp);
  1011. #else
  1012. (void) dir, (void) fn, (void) userdata;
  1013. #endif
  1014. }
  1015. static void *p_open(const char *path, int flags) {
  1016. const char *mode = flags == MG_FS_READ ? "rb" : "a+b";
  1017. #if MG_ARCH == MG_ARCH_WIN32
  1018. wchar_t b1[MG_PATH_MAX], b2[10];
  1019. MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
  1020. MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
  1021. return (void *) _wfopen(b1, b2);
  1022. #else
  1023. return (void *) fopen(path, mode);
  1024. #endif
  1025. }
  1026. static void p_close(void *fp) {
  1027. fclose((FILE *) fp);
  1028. }
  1029. static size_t p_read(void *fp, void *buf, size_t len) {
  1030. return fread(buf, 1, len, (FILE *) fp);
  1031. }
  1032. static size_t p_write(void *fp, const void *buf, size_t len) {
  1033. return fwrite(buf, 1, len, (FILE *) fp);
  1034. }
  1035. static size_t p_seek(void *fp, size_t offset) {
  1036. #if (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) || \
  1037. (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
  1038. (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
  1039. if (fseeko((FILE *) fp, (off_t) offset, SEEK_SET) != 0) (void) 0;
  1040. #else
  1041. if (fseek((FILE *) fp, (long) offset, SEEK_SET) != 0) (void) 0;
  1042. #endif
  1043. return (size_t) ftell((FILE *) fp);
  1044. }
  1045. static bool p_rename(const char *from, const char *to) {
  1046. return rename(from, to) == 0;
  1047. }
  1048. static bool p_remove(const char *path) {
  1049. return remove(path) == 0;
  1050. }
  1051. static bool p_mkdir(const char *path) {
  1052. return mkdir(path, 0775) == 0;
  1053. }
  1054. #else
  1055. static int p_stat(const char *path, size_t *size, time_t *mtime) {
  1056. (void) path, (void) size, (void) mtime;
  1057. return 0;
  1058. }
  1059. static void p_list(const char *path, void (*fn)(const char *, void *),
  1060. void *userdata) {
  1061. (void) path, (void) fn, (void) userdata;
  1062. }
  1063. static void *p_open(const char *path, int flags) {
  1064. (void) path, (void) flags;
  1065. return NULL;
  1066. }
  1067. static void p_close(void *fp) {
  1068. (void) fp;
  1069. }
  1070. static size_t p_read(void *fd, void *buf, size_t len) {
  1071. (void) fd, (void) buf, (void) len;
  1072. return 0;
  1073. }
  1074. static size_t p_write(void *fd, const void *buf, size_t len) {
  1075. (void) fd, (void) buf, (void) len;
  1076. return 0;
  1077. }
  1078. static size_t p_seek(void *fd, size_t offset) {
  1079. (void) fd, (void) offset;
  1080. return (size_t) ~0;
  1081. }
  1082. static bool p_rename(const char *from, const char *to) {
  1083. (void) from, (void) to;
  1084. return false;
  1085. }
  1086. static bool p_remove(const char *path) {
  1087. (void) path;
  1088. return false;
  1089. }
  1090. static bool p_mkdir(const char *path) {
  1091. (void) path;
  1092. return false;
  1093. }
  1094. #endif
  1095. struct mg_fs mg_fs_posix = {p_stat, p_list, p_open, p_close, p_read,
  1096. p_write, p_seek, p_rename, p_remove, p_mkdir};
  1097. #ifdef MG_ENABLE_LINES
  1098. #line 1 "src/http.c"
  1099. #endif
  1100. // Chunk deletion marker is the MSB in the "processed" counter
  1101. #define MG_DMARK ((size_t) 1 << (sizeof(size_t) * 8 - 1))
  1102. // Multipart POST example:
  1103. // --xyz
  1104. // Content-Disposition: form-data; name="val"
  1105. //
  1106. // abcdef
  1107. // --xyz
  1108. // Content-Disposition: form-data; name="foo"; filename="a.txt"
  1109. // Content-Type: text/plain
  1110. //
  1111. // hello world
  1112. //
  1113. // --xyz--
  1114. size_t mg_http_next_multipart(struct mg_str body, size_t ofs,
  1115. struct mg_http_part *part) {
  1116. struct mg_str cd = mg_str_n("Content-Disposition", 19);
  1117. const char *s = body.ptr;
  1118. size_t b = ofs, h1, h2, b1, b2, max = body.len;
  1119. // Init part params
  1120. if (part != NULL) part->name = part->filename = part->body = mg_str_n(0, 0);
  1121. // Skip boundary
  1122. while (b + 2 < max && s[b] != '\r' && s[b + 1] != '\n') b++;
  1123. if (b <= ofs || b + 2 >= max) return 0;
  1124. // MG_INFO(("B: %zu %zu [%.*s]", ofs, b - ofs, (int) (b - ofs), s));
  1125. // Skip headers
  1126. h1 = h2 = b + 2;
  1127. for (;;) {
  1128. while (h2 + 2 < max && s[h2] != '\r' && s[h2 + 1] != '\n') h2++;
  1129. if (h2 == h1) break;
  1130. if (h2 + 2 >= max) return 0;
  1131. // MG_INFO(("Header: [%.*s]", (int) (h2 - h1), &s[h1]));
  1132. if (part != NULL && h1 + cd.len + 2 < h2 && s[h1 + cd.len] == ':' &&
  1133. mg_ncasecmp(&s[h1], cd.ptr, cd.len) == 0) {
  1134. struct mg_str v = mg_str_n(&s[h1 + cd.len + 2], h2 - (h1 + cd.len + 2));
  1135. part->name = mg_http_get_header_var(v, mg_str_n("name", 4));
  1136. part->filename = mg_http_get_header_var(v, mg_str_n("filename", 8));
  1137. }
  1138. h1 = h2 = h2 + 2;
  1139. }
  1140. b1 = b2 = h2 + 2;
  1141. while (b2 + 2 + (b - ofs) + 2 < max && !(s[b2] == '\r' && s[b2 + 1] == '\n' &&
  1142. memcmp(&s[b2 + 2], s, b - ofs) == 0))
  1143. b2++;
  1144. if (b2 + 2 >= max) return 0;
  1145. if (part != NULL) part->body = mg_str_n(&s[b1], b2 - b1);
  1146. // MG_INFO(("Body: [%.*s]", (int) (b2 - b1), &s[b1]));
  1147. return b2 + 2;
  1148. }
  1149. void mg_http_bauth(struct mg_connection *c, const char *user,
  1150. const char *pass) {
  1151. struct mg_str u = mg_str(user), p = mg_str(pass);
  1152. size_t need = c->send.len + 36 + (u.len + p.len) * 2;
  1153. if (c->send.size < need) mg_iobuf_resize(&c->send, need);
  1154. if (c->send.size >= need) {
  1155. int i, n = 0;
  1156. char *buf = (char *) &c->send.buf[c->send.len];
  1157. memcpy(buf, "Authorization: Basic ", 21); // DON'T use mg_send!
  1158. for (i = 0; i < (int) u.len; i++) {
  1159. n = mg_base64_update(((unsigned char *) u.ptr)[i], buf + 21, n);
  1160. }
  1161. if (p.len > 0) {
  1162. n = mg_base64_update(':', buf + 21, n);
  1163. for (i = 0; i < (int) p.len; i++) {
  1164. n = mg_base64_update(((unsigned char *) p.ptr)[i], buf + 21, n);
  1165. }
  1166. }
  1167. n = mg_base64_final(buf + 21, n);
  1168. c->send.len += 21 + (size_t) n + 2;
  1169. memcpy(&c->send.buf[c->send.len - 2], "\r\n", 2);
  1170. } else {
  1171. MG_ERROR(("%lu oom %d->%d ", c->id, (int) c->send.size, (int) need));
  1172. }
  1173. }
  1174. struct mg_str mg_http_var(struct mg_str buf, struct mg_str name) {
  1175. struct mg_str k, v, result = mg_str_n(NULL, 0);
  1176. while (mg_split(&buf, &k, &v, '&')) {
  1177. if (name.len == k.len && mg_ncasecmp(name.ptr, k.ptr, k.len) == 0) {
  1178. result = v;
  1179. break;
  1180. }
  1181. }
  1182. return result;
  1183. }
  1184. int mg_http_get_var(const struct mg_str *buf, const char *name, char *dst,
  1185. size_t dst_len) {
  1186. int len;
  1187. if (dst == NULL || dst_len == 0) {
  1188. len = -2; // Bad destination
  1189. } else if (buf->ptr == NULL || name == NULL || buf->len == 0) {
  1190. len = -1; // Bad source
  1191. dst[0] = '\0';
  1192. } else {
  1193. struct mg_str v = mg_http_var(*buf, mg_str(name));
  1194. if (v.ptr == NULL) {
  1195. len = -4; // Name does not exist
  1196. } else {
  1197. len = mg_url_decode(v.ptr, v.len, dst, dst_len, 1);
  1198. if (len < 0) len = -3; // Failed to decode
  1199. }
  1200. }
  1201. return len;
  1202. }
  1203. static bool isx(int c) {
  1204. return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
  1205. (c >= 'A' && c <= 'F');
  1206. }
  1207. int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len,
  1208. int is_form_url_encoded) {
  1209. size_t i, j;
  1210. for (i = j = 0; i < src_len && j + 1 < dst_len; i++, j++) {
  1211. if (src[i] == '%') {
  1212. // Use `i + 2 < src_len`, not `i < src_len - 2`, note small src_len
  1213. if (i + 2 < src_len && isx(src[i + 1]) && isx(src[i + 2])) {
  1214. mg_unhex(src + i + 1, 2, (uint8_t *) &dst[j]);
  1215. i += 2;
  1216. } else {
  1217. return -1;
  1218. }
  1219. } else if (is_form_url_encoded && src[i] == '+') {
  1220. dst[j] = ' ';
  1221. } else {
  1222. dst[j] = src[i];
  1223. }
  1224. }
  1225. if (j < dst_len) dst[j] = '\0'; // Null-terminate the destination
  1226. return i >= src_len && j < dst_len ? (int) j : -1;
  1227. }
  1228. static bool isok(uint8_t c) { return c == '\n' || c == '\r' || c >= ' '; }
  1229. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len) {
  1230. size_t i;
  1231. for (i = 0; i < buf_len; i++) {
  1232. if (!isok(buf[i])) return -1;
  1233. if ((i > 0 && buf[i] == '\n' && buf[i - 1] == '\n') ||
  1234. (i > 3 && buf[i] == '\n' && buf[i - 1] == '\r' && buf[i - 2] == '\n'))
  1235. return (int) i + 1;
  1236. }
  1237. return 0;
  1238. }
  1239. static const char *skip(const char *s, const char *e, const char *d,
  1240. struct mg_str *v) {
  1241. v->ptr = s;
  1242. while (s < e && *s != '\n' && strchr(d, *s) == NULL) s++;
  1243. v->len = (size_t) (s - v->ptr);
  1244. while (s < e && strchr(d, *s) != NULL) s++;
  1245. return s;
  1246. }
  1247. struct mg_str *mg_http_get_header(struct mg_http_message *h, const char *name) {
  1248. size_t i, n = strlen(name), max = sizeof(h->headers) / sizeof(h->headers[0]);
  1249. for (i = 0; i < max && h->headers[i].name.len > 0; i++) {
  1250. struct mg_str *k = &h->headers[i].name, *v = &h->headers[i].value;
  1251. if (n == k->len && mg_ncasecmp(k->ptr, name, n) == 0) return v;
  1252. }
  1253. return NULL;
  1254. }
  1255. static void mg_http_parse_headers(const char *s, const char *end,
  1256. struct mg_http_header *h, int max_headers) {
  1257. int i;
  1258. for (i = 0; i < max_headers; i++) {
  1259. struct mg_str k, v, tmp;
  1260. const char *he = skip(s, end, "\n", &tmp);
  1261. s = skip(s, he, ": \r\n", &k);
  1262. s = skip(s, he, "\r\n", &v);
  1263. if (k.len == tmp.len) continue;
  1264. while (v.len > 0 && v.ptr[v.len - 1] == ' ') v.len--; // Trim spaces
  1265. if (k.len == 0) break;
  1266. // MG_INFO(("--HH [%.*s] [%.*s] [%.*s]", (int) tmp.len - 1, tmp.ptr,
  1267. //(int) k.len, k.ptr, (int) v.len, v.ptr));
  1268. h[i].name = k;
  1269. h[i].value = v;
  1270. }
  1271. }
  1272. int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) {
  1273. int is_response, req_len = mg_http_get_request_len((unsigned char *) s, len);
  1274. const char *end = s == NULL ? NULL : s + req_len, *qs; // Cannot add to NULL
  1275. struct mg_str *cl;
  1276. memset(hm, 0, sizeof(*hm));
  1277. if (req_len <= 0) return req_len;
  1278. hm->message.ptr = hm->head.ptr = s;
  1279. hm->body.ptr = end;
  1280. hm->head.len = (size_t) req_len;
  1281. hm->chunk.ptr = end;
  1282. hm->message.len = hm->body.len = (size_t) ~0; // Set body length to infinite
  1283. // Parse request line
  1284. s = skip(s, end, " ", &hm->method);
  1285. s = skip(s, end, " ", &hm->uri);
  1286. s = skip(s, end, "\r\n", &hm->proto);
  1287. // Sanity check. Allow protocol/reason to be empty
  1288. if (hm->method.len == 0 || hm->uri.len == 0) return -1;
  1289. // If URI contains '?' character, setup query string
  1290. if ((qs = (const char *) memchr(hm->uri.ptr, '?', hm->uri.len)) != NULL) {
  1291. hm->query.ptr = qs + 1;
  1292. hm->query.len = (size_t) (&hm->uri.ptr[hm->uri.len] - (qs + 1));
  1293. hm->uri.len = (size_t) (qs - hm->uri.ptr);
  1294. }
  1295. mg_http_parse_headers(s, end, hm->headers,
  1296. sizeof(hm->headers) / sizeof(hm->headers[0]));
  1297. if ((cl = mg_http_get_header(hm, "Content-Length")) != NULL) {
  1298. hm->body.len = (size_t) mg_to64(*cl);
  1299. hm->message.len = (size_t) req_len + hm->body.len;
  1300. }
  1301. // mg_http_parse() is used to parse both HTTP requests and HTTP
  1302. // responses. If HTTP response does not have Content-Length set, then
  1303. // body is read until socket is closed, i.e. body.len is infinite (~0).
  1304. //
  1305. // For HTTP requests though, according to
  1306. // http://tools.ietf.org/html/rfc7231#section-8.1.3,
  1307. // only POST and PUT methods have defined body semantics.
  1308. // Therefore, if Content-Length is not specified and methods are
  1309. // not one of PUT or POST, set body length to 0.
  1310. //
  1311. // So, if it is HTTP request, and Content-Length is not set,
  1312. // and method is not (PUT or POST) then reset body length to zero.
  1313. is_response = mg_ncasecmp(hm->method.ptr, "HTTP/", 5) == 0;
  1314. if (hm->body.len == (size_t) ~0 && !is_response &&
  1315. mg_vcasecmp(&hm->method, "PUT") != 0 &&
  1316. mg_vcasecmp(&hm->method, "POST") != 0) {
  1317. hm->body.len = 0;
  1318. hm->message.len = (size_t) req_len;
  1319. }
  1320. // The 204 (No content) responses also have 0 body length
  1321. if (hm->body.len == (size_t) ~0 && is_response &&
  1322. mg_vcasecmp(&hm->uri, "204") == 0) {
  1323. hm->body.len = 0;
  1324. hm->message.len = (size_t) req_len;
  1325. }
  1326. return req_len;
  1327. }
  1328. static void mg_http_vprintf_chunk(struct mg_connection *c, const char *fmt,
  1329. va_list *ap) {
  1330. size_t len = c->send.len;
  1331. mg_send(c, " \r\n", 10);
  1332. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  1333. if (c->send.len >= len + 10) {
  1334. mg_snprintf((char *) c->send.buf + len, 9, "%08lx", c->send.len - len - 10);
  1335. c->send.buf[len + 8] = '\r';
  1336. if (c->send.len == len + 10) c->is_resp = 0; // Last chunk, reset marker
  1337. }
  1338. mg_send(c, "\r\n", 2);
  1339. }
  1340. void mg_http_printf_chunk(struct mg_connection *c, const char *fmt, ...) {
  1341. va_list ap;
  1342. va_start(ap, fmt);
  1343. mg_http_vprintf_chunk(c, fmt, &ap);
  1344. va_end(ap);
  1345. }
  1346. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len) {
  1347. mg_printf(c, "%lx\r\n", (unsigned long) len);
  1348. mg_send(c, buf, len);
  1349. mg_send(c, "\r\n", 2);
  1350. if (len == 0) c->is_resp = 0;
  1351. }
  1352. // clang-format off
  1353. static const char *mg_http_status_code_str(int status_code) {
  1354. switch (status_code) {
  1355. case 100: return "Continue";
  1356. case 201: return "Created";
  1357. case 202: return "Accepted";
  1358. case 204: return "No Content";
  1359. case 206: return "Partial Content";
  1360. case 301: return "Moved Permanently";
  1361. case 302: return "Found";
  1362. case 304: return "Not Modified";
  1363. case 400: return "Bad Request";
  1364. case 401: return "Unauthorized";
  1365. case 403: return "Forbidden";
  1366. case 404: return "Not Found";
  1367. case 418: return "I'm a teapot";
  1368. case 500: return "Internal Server Error";
  1369. case 501: return "Not Implemented";
  1370. default: return "OK";
  1371. }
  1372. }
  1373. // clang-format on
  1374. void mg_http_reply(struct mg_connection *c, int code, const char *headers,
  1375. const char *fmt, ...) {
  1376. va_list ap;
  1377. size_t len;
  1378. mg_printf(c, "HTTP/1.1 %d %s\r\n%sContent-Length: \r\n\r\n", code,
  1379. mg_http_status_code_str(code), headers == NULL ? "" : headers);
  1380. len = c->send.len;
  1381. va_start(ap, fmt);
  1382. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
  1383. va_end(ap);
  1384. if (c->send.len > 16) {
  1385. size_t n = mg_snprintf((char *) &c->send.buf[len - 15], 11, "%-10lu",
  1386. (unsigned long) (c->send.len - len));
  1387. c->send.buf[len - 15 + n] = ' '; // Change ending 0 to space
  1388. }
  1389. c->is_resp = 0;
  1390. }
  1391. static void http_cb(struct mg_connection *, int, void *, void *);
  1392. static void restore_http_cb(struct mg_connection *c) {
  1393. mg_fs_close((struct mg_fd *) c->pfn_data);
  1394. c->pfn_data = NULL;
  1395. c->pfn = http_cb;
  1396. c->is_resp = 0;
  1397. }
  1398. char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime);
  1399. char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime) {
  1400. mg_snprintf(buf, len, "\"%lld.%lld\"", (int64_t) mtime, (int64_t) size);
  1401. return buf;
  1402. }
  1403. static void static_cb(struct mg_connection *c, int ev, void *ev_data,
  1404. void *fn_data) {
  1405. if (ev == MG_EV_WRITE || ev == MG_EV_POLL) {
  1406. struct mg_fd *fd = (struct mg_fd *) fn_data;
  1407. // Read to send IO buffer directly, avoid extra on-stack buffer
  1408. size_t n, max = MG_IO_SIZE, space;
  1409. size_t *cl = (size_t *) &c->data[(sizeof(c->data) - sizeof(size_t)) /
  1410. sizeof(size_t) * sizeof(size_t)];
  1411. if (c->send.size < max) mg_iobuf_resize(&c->send, max);
  1412. if (c->send.len >= c->send.size) return; // Rate limit
  1413. if ((space = c->send.size - c->send.len) > *cl) space = *cl;
  1414. n = fd->fs->rd(fd->fd, c->send.buf + c->send.len, space);
  1415. c->send.len += n;
  1416. *cl -= n;
  1417. if (n == 0) restore_http_cb(c);
  1418. } else if (ev == MG_EV_CLOSE) {
  1419. restore_http_cb(c);
  1420. }
  1421. (void) ev_data;
  1422. }
  1423. // Known mime types. Keep it outside guess_content_type() function, since
  1424. // some environments don't like it defined there.
  1425. // clang-format off
  1426. static struct mg_str s_known_types[] = {
  1427. MG_C_STR("html"), MG_C_STR("text/html; charset=utf-8"),
  1428. MG_C_STR("htm"), MG_C_STR("text/html; charset=utf-8"),
  1429. MG_C_STR("css"), MG_C_STR("text/css; charset=utf-8"),
  1430. MG_C_STR("js"), MG_C_STR("text/javascript; charset=utf-8"),
  1431. MG_C_STR("gif"), MG_C_STR("image/gif"),
  1432. MG_C_STR("png"), MG_C_STR("image/png"),
  1433. MG_C_STR("jpg"), MG_C_STR("image/jpeg"),
  1434. MG_C_STR("jpeg"), MG_C_STR("image/jpeg"),
  1435. MG_C_STR("woff"), MG_C_STR("font/woff"),
  1436. MG_C_STR("ttf"), MG_C_STR("font/ttf"),
  1437. MG_C_STR("svg"), MG_C_STR("image/svg+xml"),
  1438. MG_C_STR("txt"), MG_C_STR("text/plain; charset=utf-8"),
  1439. MG_C_STR("avi"), MG_C_STR("video/x-msvideo"),
  1440. MG_C_STR("csv"), MG_C_STR("text/csv"),
  1441. MG_C_STR("doc"), MG_C_STR("application/msword"),
  1442. MG_C_STR("exe"), MG_C_STR("application/octet-stream"),
  1443. MG_C_STR("gz"), MG_C_STR("application/gzip"),
  1444. MG_C_STR("ico"), MG_C_STR("image/x-icon"),
  1445. MG_C_STR("json"), MG_C_STR("application/json"),
  1446. MG_C_STR("mov"), MG_C_STR("video/quicktime"),
  1447. MG_C_STR("mp3"), MG_C_STR("audio/mpeg"),
  1448. MG_C_STR("mp4"), MG_C_STR("video/mp4"),
  1449. MG_C_STR("mpeg"), MG_C_STR("video/mpeg"),
  1450. MG_C_STR("pdf"), MG_C_STR("application/pdf"),
  1451. MG_C_STR("shtml"), MG_C_STR("text/html; charset=utf-8"),
  1452. MG_C_STR("tgz"), MG_C_STR("application/tar-gz"),
  1453. MG_C_STR("wav"), MG_C_STR("audio/wav"),
  1454. MG_C_STR("webp"), MG_C_STR("image/webp"),
  1455. MG_C_STR("zip"), MG_C_STR("application/zip"),
  1456. MG_C_STR("3gp"), MG_C_STR("video/3gpp"),
  1457. {0, 0},
  1458. };
  1459. // clang-format on
  1460. static struct mg_str guess_content_type(struct mg_str path, const char *extra) {
  1461. struct mg_str k, v, s = mg_str(extra);
  1462. size_t i = 0;
  1463. // Shrink path to its extension only
  1464. while (i < path.len && path.ptr[path.len - i - 1] != '.') i++;
  1465. path.ptr += path.len - i;
  1466. path.len = i;
  1467. // Process user-provided mime type overrides, if any
  1468. while (mg_commalist(&s, &k, &v)) {
  1469. if (mg_strcmp(path, k) == 0) return v;
  1470. }
  1471. // Process built-in mime types
  1472. for (i = 0; s_known_types[i].ptr != NULL; i += 2) {
  1473. if (mg_strcmp(path, s_known_types[i]) == 0) return s_known_types[i + 1];
  1474. }
  1475. return mg_str("text/plain; charset=utf-8");
  1476. }
  1477. static int getrange(struct mg_str *s, int64_t *a, int64_t *b) {
  1478. size_t i, numparsed = 0;
  1479. // MG_INFO(("%.*s", (int) s->len, s->ptr));
  1480. for (i = 0; i + 6 < s->len; i++) {
  1481. if (memcmp(&s->ptr[i], "bytes=", 6) == 0) {
  1482. struct mg_str p = mg_str_n(s->ptr + i + 6, s->len - i - 6);
  1483. if (p.len > 0 && p.ptr[0] >= '0' && p.ptr[0] <= '9') numparsed++;
  1484. *a = mg_to64(p);
  1485. // MG_INFO(("PPP [%.*s] %d", (int) p.len, p.ptr, numparsed));
  1486. while (p.len && p.ptr[0] >= '0' && p.ptr[0] <= '9') p.ptr++, p.len--;
  1487. if (p.len && p.ptr[0] == '-') p.ptr++, p.len--;
  1488. *b = mg_to64(p);
  1489. if (p.len > 0 && p.ptr[0] >= '0' && p.ptr[0] <= '9') numparsed++;
  1490. // MG_INFO(("PPP [%.*s] %d", (int) p.len, p.ptr, numparsed));
  1491. break;
  1492. }
  1493. }
  1494. return (int) numparsed;
  1495. }
  1496. void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
  1497. const char *path,
  1498. const struct mg_http_serve_opts *opts) {
  1499. char etag[64], tmp[MG_PATH_MAX];
  1500. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  1501. struct mg_fd *fd = path == NULL ? NULL : mg_fs_open(fs, path, MG_FS_READ);
  1502. size_t size = 0;
  1503. time_t mtime = 0;
  1504. struct mg_str *inm = NULL;
  1505. struct mg_str mime = guess_content_type(mg_str(path), opts->mime_types);
  1506. bool gzip = false;
  1507. // If file does not exist, we try to open file PATH.gz - and if such
  1508. // pre-compressed .gz file exists, serve it with the Content-Encoding: gzip
  1509. // Note - we ignore Accept-Encoding, cause we don't have a choice
  1510. if (fd == NULL) {
  1511. MG_DEBUG(("NULL [%s]", path));
  1512. mg_snprintf(tmp, sizeof(tmp), "%s.gz", path);
  1513. if ((fd = mg_fs_open(fs, tmp, MG_FS_READ)) != NULL) {
  1514. gzip = true;
  1515. path = tmp;
  1516. } else if (opts->page404 != NULL) {
  1517. // No precompressed file, serve 404
  1518. fd = mg_fs_open(fs, opts->page404, MG_FS_READ);
  1519. mime = guess_content_type(mg_str(path), opts->mime_types);
  1520. path = opts->page404;
  1521. }
  1522. }
  1523. if (fd == NULL || fs->st(path, &size, &mtime) == 0) {
  1524. mg_http_reply(c, 404, opts->extra_headers, "Not found\n");
  1525. mg_fs_close(fd);
  1526. // NOTE: mg_http_etag() call should go first!
  1527. } else if (mg_http_etag(etag, sizeof(etag), size, mtime) != NULL &&
  1528. (inm = mg_http_get_header(hm, "If-None-Match")) != NULL &&
  1529. mg_vcasecmp(inm, etag) == 0) {
  1530. mg_fs_close(fd);
  1531. mg_http_reply(c, 304, opts->extra_headers, "");
  1532. } else {
  1533. int n, status = 200;
  1534. char range[100];
  1535. int64_t r1 = 0, r2 = 0, cl = (int64_t) size;
  1536. // Handle Range header
  1537. struct mg_str *rh = mg_http_get_header(hm, "Range");
  1538. range[0] = '\0';
  1539. if (rh != NULL && (n = getrange(rh, &r1, &r2)) > 0 && r1 >= 0 && r2 >= 0) {
  1540. // If range is specified like "400-", set second limit to content len
  1541. if (n == 1) r2 = cl - 1;
  1542. if (r1 > r2 || r2 >= cl) {
  1543. status = 416;
  1544. cl = 0;
  1545. mg_snprintf(range, sizeof(range), "Content-Range: bytes */%lld\r\n",
  1546. (int64_t) size);
  1547. } else {
  1548. status = 206;
  1549. cl = r2 - r1 + 1;
  1550. mg_snprintf(range, sizeof(range),
  1551. "Content-Range: bytes %lld-%lld/%lld\r\n", r1, r1 + cl - 1,
  1552. (int64_t) size);
  1553. fs->sk(fd->fd, (size_t) r1);
  1554. }
  1555. }
  1556. mg_printf(c,
  1557. "HTTP/1.1 %d %s\r\n"
  1558. "Content-Type: %.*s\r\n"
  1559. "Etag: %s\r\n"
  1560. "Content-Length: %llu\r\n"
  1561. "%s%s%s\r\n",
  1562. status, mg_http_status_code_str(status), (int) mime.len, mime.ptr,
  1563. etag, cl, gzip ? "Content-Encoding: gzip\r\n" : "", range,
  1564. opts->extra_headers ? opts->extra_headers : "");
  1565. if (mg_vcasecmp(&hm->method, "HEAD") == 0) {
  1566. c->is_draining = 1;
  1567. c->is_resp = 0;
  1568. mg_fs_close(fd);
  1569. } else {
  1570. // Track to-be-sent content length at the end of c->data, aligned
  1571. size_t *clp = (size_t *) &c->data[(sizeof(c->data) - sizeof(size_t)) /
  1572. sizeof(size_t) * sizeof(size_t)];
  1573. c->pfn = static_cb;
  1574. c->pfn_data = fd;
  1575. *clp = (size_t) cl;
  1576. }
  1577. }
  1578. }
  1579. struct printdirentrydata {
  1580. struct mg_connection *c;
  1581. struct mg_http_message *hm;
  1582. const struct mg_http_serve_opts *opts;
  1583. const char *dir;
  1584. };
  1585. static void printdirentry(const char *name, void *userdata) {
  1586. struct printdirentrydata *d = (struct printdirentrydata *) userdata;
  1587. struct mg_fs *fs = d->opts->fs == NULL ? &mg_fs_posix : d->opts->fs;
  1588. size_t size = 0;
  1589. time_t t = 0;
  1590. char path[MG_PATH_MAX], sz[40], mod[40];
  1591. int flags, n = 0;
  1592. // MG_DEBUG(("[%s] [%s]", d->dir, name));
  1593. if (mg_snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) >
  1594. sizeof(path)) {
  1595. MG_ERROR(("%s truncated", name));
  1596. } else if ((flags = fs->st(path, &size, &t)) == 0) {
  1597. MG_ERROR(("%lu stat(%s): %d", d->c->id, path, errno));
  1598. } else {
  1599. const char *slash = flags & MG_FS_DIR ? "/" : "";
  1600. if (flags & MG_FS_DIR) {
  1601. mg_snprintf(sz, sizeof(sz), "%s", "[DIR]");
  1602. } else {
  1603. mg_snprintf(sz, sizeof(sz), "%lld", (uint64_t) size);
  1604. }
  1605. #if defined(MG_HTTP_DIRLIST_TIME_FMT)
  1606. {
  1607. char time_str[40];
  1608. struct tm *time_info = localtime(&t);
  1609. strftime(time_str, sizeof time_str, "%Y/%m/%d %H:%M:%S", time_info);
  1610. mg_snprintf(mod, sizeof(mod), "%s", time_str);
  1611. }
  1612. #else
  1613. mg_snprintf(mod, sizeof(mod), "%lu", (unsigned long) t);
  1614. #endif
  1615. n = (int) mg_url_encode(name, strlen(name), path, sizeof(path));
  1616. mg_printf(d->c,
  1617. " <tr><td><a href=\"%.*s%s\">%s%s</a></td>"
  1618. "<td name=%lu>%s</td><td name=%lld>%s</td></tr>\n",
  1619. n, path, slash, name, slash, (unsigned long) t, mod,
  1620. flags & MG_FS_DIR ? (int64_t) -1 : (int64_t) size, sz);
  1621. }
  1622. }
  1623. static void listdir(struct mg_connection *c, struct mg_http_message *hm,
  1624. const struct mg_http_serve_opts *opts, char *dir) {
  1625. const char *sort_js_code =
  1626. "<script>function srt(tb, sc, so, d) {"
  1627. "var tr = Array.prototype.slice.call(tb.rows, 0),"
  1628. "tr = tr.sort(function (a, b) { var c1 = a.cells[sc], c2 = b.cells[sc],"
  1629. "n1 = c1.getAttribute('name'), n2 = c2.getAttribute('name'), "
  1630. "t1 = a.cells[2].getAttribute('name'), "
  1631. "t2 = b.cells[2].getAttribute('name'); "
  1632. "return so * (t1 < 0 && t2 >= 0 ? -1 : t2 < 0 && t1 >= 0 ? 1 : "
  1633. "n1 ? parseInt(n2) - parseInt(n1) : "
  1634. "c1.textContent.trim().localeCompare(c2.textContent.trim())); });";
  1635. const char *sort_js_code2 =
  1636. "for (var i = 0; i < tr.length; i++) tb.appendChild(tr[i]); "
  1637. "if (!d) window.location.hash = ('sc=' + sc + '&so=' + so); "
  1638. "};"
  1639. "window.onload = function() {"
  1640. "var tb = document.getElementById('tb');"
  1641. "var m = /sc=([012]).so=(1|-1)/.exec(window.location.hash) || [0, 2, 1];"
  1642. "var sc = m[1], so = m[2]; document.onclick = function(ev) { "
  1643. "var c = ev.target.rel; if (c) {if (c == sc) so *= -1; srt(tb, c, so); "
  1644. "sc = c; ev.preventDefault();}};"
  1645. "srt(tb, sc, so, true);"
  1646. "}"
  1647. "</script>";
  1648. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  1649. struct printdirentrydata d = {c, hm, opts, dir};
  1650. char tmp[10], buf[MG_PATH_MAX];
  1651. size_t off, n;
  1652. int len = mg_url_decode(hm->uri.ptr, hm->uri.len, buf, sizeof(buf), 0);
  1653. struct mg_str uri = len > 0 ? mg_str_n(buf, (size_t) len) : hm->uri;
  1654. mg_printf(c,
  1655. "HTTP/1.1 200 OK\r\n"
  1656. "Content-Type: text/html; charset=utf-8\r\n"
  1657. "%s"
  1658. "Content-Length: \r\n\r\n",
  1659. opts->extra_headers == NULL ? "" : opts->extra_headers);
  1660. off = c->send.len; // Start of body
  1661. mg_printf(c,
  1662. "<!DOCTYPE html><html><head><title>Index of %.*s</title>%s%s"
  1663. "<style>th,td {text-align: left; padding-right: 1em; "
  1664. "font-family: monospace; }</style></head>"
  1665. "<body><h1>Index of %.*s</h1><table cellpadding=\"0\"><thead>"
  1666. "<tr><th><a href=\"#\" rel=\"0\">Name</a></th><th>"
  1667. "<a href=\"#\" rel=\"1\">Modified</a></th>"
  1668. "<th><a href=\"#\" rel=\"2\">Size</a></th></tr>"
  1669. "<tr><td colspan=\"3\"><hr></td></tr>"
  1670. "</thead>"
  1671. "<tbody id=\"tb\">\n",
  1672. (int) uri.len, uri.ptr, sort_js_code, sort_js_code2, (int) uri.len,
  1673. uri.ptr);
  1674. mg_printf(c, "%s",
  1675. " <tr><td><a href=\"..\">..</a></td>"
  1676. "<td name=-1></td><td name=-1>[DIR]</td></tr>\n");
  1677. fs->ls(dir, printdirentry, &d);
  1678. mg_printf(c,
  1679. "</tbody><tfoot><tr><td colspan=\"3\"><hr></td></tr></tfoot>"
  1680. "</table><address>Mongoose v.%s</address></body></html>\n",
  1681. MG_VERSION);
  1682. n = mg_snprintf(tmp, sizeof(tmp), "%lu", (unsigned long) (c->send.len - off));
  1683. if (n > sizeof(tmp)) n = 0;
  1684. memcpy(c->send.buf + off - 12, tmp, n); // Set content length
  1685. c->is_resp = 0; // Mark response end
  1686. }
  1687. // Resolve requested file into `path` and return its fs->st() result
  1688. static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm,
  1689. struct mg_fs *fs, struct mg_str url, struct mg_str dir,
  1690. char *path, size_t path_size) {
  1691. int flags, tmp;
  1692. // Append URI to the root_dir, and sanitize it
  1693. size_t n = mg_snprintf(path, path_size, "%.*s", (int) dir.len, dir.ptr);
  1694. if (n > path_size) n = path_size;
  1695. path[path_size - 1] = '\0';
  1696. if (n + 2 < path_size) path[n++] = '/', path[n] = '\0';
  1697. mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n,
  1698. path_size - n, 0);
  1699. path[path_size - 1] = '\0'; // Double-check
  1700. mg_remove_double_dots(path);
  1701. n = strlen(path);
  1702. while (n > 1 && path[n - 1] == '/') path[--n] = 0; // Trim trailing slashes
  1703. flags = mg_vcmp(&hm->uri, "/") == 0 ? MG_FS_DIR : fs->st(path, NULL, NULL);
  1704. MG_VERBOSE(("%lu %.*s -> %s %d", c->id, (int) hm->uri.len, hm->uri.ptr, path,
  1705. flags));
  1706. if (flags == 0) {
  1707. // Do nothing - let's caller decide
  1708. } else if ((flags & MG_FS_DIR) && hm->uri.len > 0 &&
  1709. hm->uri.ptr[hm->uri.len - 1] != '/') {
  1710. mg_printf(c,
  1711. "HTTP/1.1 301 Moved\r\n"
  1712. "Location: %.*s/\r\n"
  1713. "Content-Length: 0\r\n"
  1714. "\r\n",
  1715. (int) hm->uri.len, hm->uri.ptr);
  1716. c->is_resp = 0;
  1717. flags = -1;
  1718. } else if (flags & MG_FS_DIR) {
  1719. if (((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX) > 0 &&
  1720. (tmp = fs->st(path, NULL, NULL)) != 0) ||
  1721. (mg_snprintf(path + n, path_size - n, "/index.shtml") > 0 &&
  1722. (tmp = fs->st(path, NULL, NULL)) != 0))) {
  1723. flags = tmp;
  1724. } else if ((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX ".gz") >
  1725. 0 &&
  1726. (tmp = fs->st(path, NULL, NULL)) !=
  1727. 0)) { // check for gzipped index
  1728. flags = tmp;
  1729. path[n + 1 + strlen(MG_HTTP_INDEX)] =
  1730. '\0'; // Remove appended .gz in index file name
  1731. } else {
  1732. path[n] = '\0'; // Remove appended index file name
  1733. }
  1734. }
  1735. return flags;
  1736. }
  1737. static int uri_to_path(struct mg_connection *c, struct mg_http_message *hm,
  1738. const struct mg_http_serve_opts *opts, char *path,
  1739. size_t path_size) {
  1740. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  1741. struct mg_str k, v, s = mg_str(opts->root_dir), u = {0, 0}, p = {0, 0};
  1742. while (mg_commalist(&s, &k, &v)) {
  1743. if (v.len == 0) v = k, k = mg_str("/");
  1744. if (hm->uri.len < k.len) continue;
  1745. if (mg_strcmp(k, mg_str_n(hm->uri.ptr, k.len)) != 0) continue;
  1746. u = k, p = v;
  1747. }
  1748. return uri_to_path2(c, hm, fs, u, p, path, path_size);
  1749. }
  1750. void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
  1751. const struct mg_http_serve_opts *opts) {
  1752. char path[MG_PATH_MAX];
  1753. const char *sp = opts->ssi_pattern;
  1754. int flags = uri_to_path(c, hm, opts, path, sizeof(path));
  1755. if (flags < 0) {
  1756. // Do nothing: the response has already been sent by uri_to_path()
  1757. } else if (flags & MG_FS_DIR) {
  1758. listdir(c, hm, opts, path);
  1759. } else if (flags && sp != NULL &&
  1760. mg_globmatch(sp, strlen(sp), path, strlen(path))) {
  1761. mg_http_serve_ssi(c, opts->root_dir, path);
  1762. } else {
  1763. mg_http_serve_file(c, hm, path, opts);
  1764. }
  1765. }
  1766. static bool mg_is_url_safe(int c) {
  1767. return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
  1768. (c >= 'A' && c <= 'Z') || c == '.' || c == '_' || c == '-' || c == '~';
  1769. }
  1770. size_t mg_url_encode(const char *s, size_t sl, char *buf, size_t len) {
  1771. size_t i, n = 0;
  1772. for (i = 0; i < sl; i++) {
  1773. int c = *(unsigned char *) &s[i];
  1774. if (n + 4 >= len) return 0;
  1775. if (mg_is_url_safe(c)) {
  1776. buf[n++] = s[i];
  1777. } else {
  1778. buf[n++] = '%';
  1779. mg_hex(&s[i], 1, &buf[n]);
  1780. n += 2;
  1781. }
  1782. }
  1783. if (len > 0 && n < len - 1) buf[n] = '\0'; // Null-terminate the destination
  1784. if (len > 0) buf[len - 1] = '\0'; // Always.
  1785. return n;
  1786. }
  1787. void mg_http_creds(struct mg_http_message *hm, char *user, size_t userlen,
  1788. char *pass, size_t passlen) {
  1789. struct mg_str *v = mg_http_get_header(hm, "Authorization");
  1790. user[0] = pass[0] = '\0';
  1791. if (v != NULL && v->len > 6 && memcmp(v->ptr, "Basic ", 6) == 0) {
  1792. char buf[256];
  1793. int n = mg_base64_decode(v->ptr + 6, (int) v->len - 6, buf);
  1794. const char *p = (const char *) memchr(buf, ':', n > 0 ? (size_t) n : 0);
  1795. if (p != NULL) {
  1796. mg_snprintf(user, userlen, "%.*s", (int) (p - buf), buf);
  1797. mg_snprintf(pass, passlen, "%.*s", n - (int) (p - buf) - 1, p + 1);
  1798. }
  1799. } else if (v != NULL && v->len > 7 && memcmp(v->ptr, "Bearer ", 7) == 0) {
  1800. mg_snprintf(pass, passlen, "%.*s", (int) v->len - 7, v->ptr + 7);
  1801. } else if ((v = mg_http_get_header(hm, "Cookie")) != NULL) {
  1802. struct mg_str t = mg_http_get_header_var(*v, mg_str_n("access_token", 12));
  1803. if (t.len > 0) mg_snprintf(pass, passlen, "%.*s", (int) t.len, t.ptr);
  1804. } else {
  1805. mg_http_get_var(&hm->query, "access_token", pass, passlen);
  1806. }
  1807. }
  1808. static struct mg_str stripquotes(struct mg_str s) {
  1809. return s.len > 1 && s.ptr[0] == '"' && s.ptr[s.len - 1] == '"'
  1810. ? mg_str_n(s.ptr + 1, s.len - 2)
  1811. : s;
  1812. }
  1813. struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) {
  1814. size_t i;
  1815. for (i = 0; v.len > 0 && i + v.len + 2 < s.len; i++) {
  1816. if (s.ptr[i + v.len] == '=' && memcmp(&s.ptr[i], v.ptr, v.len) == 0) {
  1817. const char *p = &s.ptr[i + v.len + 1], *b = p, *x = &s.ptr[s.len];
  1818. int q = p < x && *p == '"' ? 1 : 0;
  1819. while (p < x &&
  1820. (q ? p == b || *p != '"' : *p != ';' && *p != ' ' && *p != ','))
  1821. p++;
  1822. // MG_INFO(("[%.*s] [%.*s] [%.*s]", (int) s.len, s.ptr, (int) v.len,
  1823. // v.ptr, (int) (p - b), b));
  1824. return stripquotes(mg_str_n(b, (size_t) (p - b + q)));
  1825. }
  1826. }
  1827. return mg_str_n(NULL, 0);
  1828. }
  1829. bool mg_http_match_uri(const struct mg_http_message *hm, const char *glob) {
  1830. return mg_match(hm->uri, mg_str(glob), NULL);
  1831. }
  1832. long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
  1833. struct mg_fs *fs, const char *path, size_t max_size) {
  1834. char buf[20] = "0";
  1835. long res = 0, offset;
  1836. mg_http_get_var(&hm->query, "offset", buf, sizeof(buf));
  1837. offset = strtol(buf, NULL, 0);
  1838. if (hm->body.len == 0) {
  1839. mg_http_reply(c, 200, "", "%ld", res); // Nothing to write
  1840. } else {
  1841. struct mg_fd *fd;
  1842. size_t current_size = 0;
  1843. MG_DEBUG(("%s -> %d bytes @ %ld", path, (int) hm->body.len, offset));
  1844. if (offset == 0) fs->rm(path); // If offset if 0, truncate file
  1845. fs->st(path, &current_size, NULL);
  1846. if (offset < 0) {
  1847. mg_http_reply(c, 400, "", "offset required");
  1848. res = -1;
  1849. } else if (offset > 0 && current_size != (size_t) offset) {
  1850. mg_http_reply(c, 400, "", "%s: offset mismatch", path);
  1851. res = -2;
  1852. } else if ((size_t) offset + hm->body.len > max_size) {
  1853. mg_http_reply(c, 400, "", "%s: over max size of %lu", path,
  1854. (unsigned long) max_size);
  1855. res = -3;
  1856. } else if ((fd = mg_fs_open(fs, path, MG_FS_WRITE)) == NULL) {
  1857. mg_http_reply(c, 400, "", "open(%s): %d", path, errno);
  1858. res = -4;
  1859. } else {
  1860. res = offset + (long) fs->wr(fd->fd, hm->body.ptr, hm->body.len);
  1861. mg_fs_close(fd);
  1862. mg_http_reply(c, 200, "", "%ld", res);
  1863. }
  1864. }
  1865. return res;
  1866. }
  1867. int mg_http_status(const struct mg_http_message *hm) {
  1868. return atoi(hm->uri.ptr);
  1869. }
  1870. // If a server sends data to the client using chunked encoding, Mongoose strips
  1871. // off the chunking prefix (hex length and \r\n) and suffix (\r\n), appends the
  1872. // stripped data to the body, and fires the MG_EV_HTTP_CHUNK event. When zero
  1873. // chunk is received, we fire MG_EV_HTTP_MSG, and the body already has all
  1874. // chunking prefixes/suffixes stripped.
  1875. //
  1876. // If a server sends data without chunked encoding, we also fire a series of
  1877. // MG_EV_HTTP_CHUNK events for every received piece of data, and then we fire
  1878. // MG_EV_HTTP_MSG event in the end.
  1879. //
  1880. // We track total processed length in the c->pfn_data, which is a void *
  1881. // pointer: we store a size_t value there.
  1882. static bool getchunk(struct mg_str s, size_t *prefixlen, size_t *datalen) {
  1883. size_t i = 0, n;
  1884. while (i < s.len && s.ptr[i] != '\r' && s.ptr[i] != '\n') i++;
  1885. n = mg_unhexn(s.ptr, i);
  1886. // MG_INFO(("%d %d", (int) (i + n + 4), (int) s.len));
  1887. if (s.len < i + n + 4) return false; // Chunk not yet fully buffered
  1888. if (s.ptr[i] != '\r' || s.ptr[i + 1] != '\n') return false;
  1889. if (s.ptr[i + n + 2] != '\r' || s.ptr[i + n + 3] != '\n') return false;
  1890. *prefixlen = i + 2;
  1891. *datalen = n;
  1892. return true;
  1893. }
  1894. static bool mg_is_chunked(struct mg_http_message *hm) {
  1895. const char *needle = "chunked";
  1896. struct mg_str *te = mg_http_get_header(hm, "Transfer-Encoding");
  1897. return te != NULL && mg_vcasecmp(te, needle) == 0;
  1898. }
  1899. void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm) {
  1900. size_t ofs = (size_t) (hm->chunk.ptr - (char *) c->recv.buf);
  1901. mg_iobuf_del(&c->recv, ofs, hm->chunk.len);
  1902. c->pfn_data = (void *) ((size_t) c->pfn_data | MG_DMARK);
  1903. }
  1904. static void deliver_chunked_chunks(struct mg_connection *c, size_t hlen,
  1905. struct mg_http_message *hm, bool *next) {
  1906. // | ... headers ... | HEXNUM\r\n ..data.. \r\n | ......
  1907. // +------------------+--------------------------+----
  1908. // | hlen | chunk1 | ......
  1909. char *buf = (char *) &c->recv.buf[hlen], *p = buf;
  1910. size_t len = c->recv.len - hlen;
  1911. size_t processed = ((size_t) c->pfn_data) & ~MG_DMARK;
  1912. size_t mark, pl, dl, del = 0, ofs = 0;
  1913. bool last = false;
  1914. if (processed <= len) len -= processed, buf += processed;
  1915. while (!last && getchunk(mg_str_n(buf + ofs, len - ofs), &pl, &dl)) {
  1916. size_t saved = c->recv.len;
  1917. memmove(p + processed, buf + ofs + pl, dl);
  1918. // MG_INFO(("P2 [%.*s]", (int) (processed + dl), p));
  1919. hm->chunk = mg_str_n(p + processed, dl);
  1920. mg_call(c, MG_EV_HTTP_CHUNK, hm);
  1921. ofs += pl + dl + 2, del += pl + 2; // 2 is for \r\n suffix
  1922. processed += dl;
  1923. if (c->recv.len != saved) processed -= dl, buf -= dl;
  1924. // mg_hexdump(c->recv.buf, hlen + processed);
  1925. last = (dl == 0);
  1926. }
  1927. mg_iobuf_del(&c->recv, hlen + processed, del);
  1928. mark = ((size_t) c->pfn_data) & MG_DMARK;
  1929. c->pfn_data = (void *) (processed | mark);
  1930. if (last) {
  1931. hm->body.len = processed;
  1932. hm->message.len = hlen + processed;
  1933. c->pfn_data = NULL;
  1934. if (mark) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
  1935. // MG_INFO(("LAST, mark: %lx", mark));
  1936. // mg_hexdump(c->recv.buf, c->recv.len);
  1937. }
  1938. }
  1939. static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
  1940. struct mg_http_message *hm, bool *next) {
  1941. size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK;
  1942. size_t deleted = ((size_t) c->pfn_data) & MG_DMARK;
  1943. hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen);
  1944. if (processed <= hm->chunk.len && !deleted) {
  1945. hm->chunk.len -= processed;
  1946. hm->chunk.ptr += processed;
  1947. }
  1948. left = hm->body.len < processed ? 0 : hm->body.len - processed;
  1949. if (hm->chunk.len > left) hm->chunk.len = left;
  1950. if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm);
  1951. processed += hm->chunk.len;
  1952. deleted = ((size_t) c->pfn_data) & MG_DMARK; // Re-evaluate after user call
  1953. if (processed >= hm->body.len) { // Last, 0-len chunk
  1954. hm->chunk.len = 0; // Reset length
  1955. mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler
  1956. c->pfn_data = NULL; // Reset processed counter
  1957. if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
  1958. } else {
  1959. c->pfn_data = (void *) (processed | deleted); // if it is set
  1960. }
  1961. }
  1962. static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
  1963. if (ev == MG_EV_READ || ev == MG_EV_CLOSE) {
  1964. struct mg_http_message hm;
  1965. // mg_hexdump(c->recv.buf, c->recv.len);
  1966. while (c->recv.buf != NULL && c->recv.len > 0) {
  1967. bool next = false;
  1968. int hlen = mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
  1969. if (hlen < 0) {
  1970. mg_error(c, "HTTP parse:\n%.*s", (int) c->recv.len, c->recv.buf);
  1971. break;
  1972. }
  1973. if (c->is_resp) break; // Response is still generated
  1974. if (hlen == 0) break; // Request is not buffered yet
  1975. if (ev == MG_EV_CLOSE) { // If client did not set Content-Length
  1976. hm.message.len = c->recv.len; // and closes now, deliver a MSG
  1977. hm.body.len = hm.message.len - (size_t) (hm.body.ptr - hm.message.ptr);
  1978. }
  1979. if (mg_is_chunked(&hm)) {
  1980. deliver_chunked_chunks(c, (size_t) hlen, &hm, &next);
  1981. } else {
  1982. deliver_normal_chunks(c, (size_t) hlen, &hm, &next);
  1983. }
  1984. if (next) continue; // Chunks & request were deleted
  1985. // Chunk events are delivered. If we have full body, deliver MSG
  1986. if (c->recv.len < hm.message.len) break;
  1987. if (c->is_accepted) c->is_resp = 1; // Start generating response
  1988. mg_call(c, MG_EV_HTTP_MSG, &hm); // User handler can clear is_resp
  1989. mg_iobuf_del(&c->recv, 0, hm.message.len);
  1990. }
  1991. }
  1992. (void) evd, (void) fnd;
  1993. }
  1994. static void mg_hfn(struct mg_connection *c, int ev, void *ev_data, void *fnd) {
  1995. if (ev == MG_EV_HTTP_MSG) {
  1996. struct mg_http_message *hm = (struct mg_http_message *) ev_data;
  1997. if (mg_http_match_uri(hm, "/quit")) {
  1998. mg_http_reply(c, 200, "", "ok\n");
  1999. c->is_draining = 1;
  2000. c->data[0] = 'X';
  2001. } else if (mg_http_match_uri(hm, "/debug")) {
  2002. int level = (int) mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG);
  2003. mg_log_set(level);
  2004. mg_http_reply(c, 200, "", "Debug level set to %d\n", level);
  2005. } else {
  2006. mg_http_reply(c, 200, "", "hi\n");
  2007. }
  2008. } else if (ev == MG_EV_CLOSE) {
  2009. if (c->data[0] == 'X') *(bool *) fnd = true;
  2010. }
  2011. }
  2012. void mg_hello(const char *url) {
  2013. struct mg_mgr mgr;
  2014. bool done = false;
  2015. mg_mgr_init(&mgr);
  2016. if (mg_http_listen(&mgr, url, mg_hfn, &done) == NULL) done = true;
  2017. while (done == false) mg_mgr_poll(&mgr, 100);
  2018. mg_mgr_free(&mgr);
  2019. }
  2020. struct mg_connection *mg_http_connect(struct mg_mgr *mgr, const char *url,
  2021. mg_event_handler_t fn, void *fn_data) {
  2022. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  2023. if (c != NULL) c->pfn = http_cb;
  2024. return c;
  2025. }
  2026. struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url,
  2027. mg_event_handler_t fn, void *fn_data) {
  2028. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  2029. if (c != NULL) c->pfn = http_cb;
  2030. return c;
  2031. }
  2032. #ifdef MG_ENABLE_LINES
  2033. #line 1 "src/iobuf.c"
  2034. #endif
  2035. // Not using memset for zeroing memory, cause it can be dropped by compiler
  2036. // See https://github.com/cesanta/mongoose/pull/1265
  2037. static void zeromem(volatile unsigned char *buf, size_t len) {
  2038. if (buf != NULL) {
  2039. while (len--) *buf++ = 0;
  2040. }
  2041. }
  2042. static size_t roundup(size_t size, size_t align) {
  2043. return align == 0 ? size : (size + align - 1) / align * align;
  2044. }
  2045. int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
  2046. int ok = 1;
  2047. new_size = roundup(new_size, io->align);
  2048. if (new_size == 0) {
  2049. zeromem(io->buf, io->size);
  2050. free(io->buf);
  2051. io->buf = NULL;
  2052. io->len = io->size = 0;
  2053. } else if (new_size != io->size) {
  2054. // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the
  2055. // porting to some obscure platforms like FreeRTOS
  2056. void *p = calloc(1, new_size);
  2057. if (p != NULL) {
  2058. size_t len = new_size < io->len ? new_size : io->len;
  2059. if (len > 0 && io->buf != NULL) memmove(p, io->buf, len);
  2060. zeromem(io->buf, io->size);
  2061. free(io->buf);
  2062. io->buf = (unsigned char *) p;
  2063. io->size = new_size;
  2064. } else {
  2065. ok = 0;
  2066. MG_ERROR(("%lld->%lld", (uint64_t) io->size, (uint64_t) new_size));
  2067. }
  2068. }
  2069. return ok;
  2070. }
  2071. int mg_iobuf_init(struct mg_iobuf *io, size_t size, size_t align) {
  2072. io->buf = NULL;
  2073. io->align = align;
  2074. io->size = io->len = 0;
  2075. return mg_iobuf_resize(io, size);
  2076. }
  2077. size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf,
  2078. size_t len) {
  2079. size_t new_size = roundup(io->len + len, io->align);
  2080. mg_iobuf_resize(io, new_size); // Attempt to resize
  2081. if (new_size != io->size) len = 0; // Resize failure, append nothing
  2082. if (ofs < io->len) memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs);
  2083. if (buf != NULL) memmove(io->buf + ofs, buf, len);
  2084. if (ofs > io->len) io->len += ofs - io->len;
  2085. io->len += len;
  2086. return len;
  2087. }
  2088. size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
  2089. if (ofs > io->len) ofs = io->len;
  2090. if (ofs + len > io->len) len = io->len - ofs;
  2091. if (io->buf) memmove(io->buf + ofs, io->buf + ofs + len, io->len - ofs - len);
  2092. if (io->buf) zeromem(io->buf + io->len - len, len);
  2093. io->len -= len;
  2094. return len;
  2095. }
  2096. void mg_iobuf_free(struct mg_iobuf *io) {
  2097. mg_iobuf_resize(io, 0);
  2098. }
  2099. #ifdef MG_ENABLE_LINES
  2100. #line 1 "src/json.c"
  2101. #endif
  2102. static const char *escapeseq(int esc) {
  2103. return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
  2104. }
  2105. static char json_esc(int c, int esc) {
  2106. const char *p, *esc1 = escapeseq(esc), *esc2 = escapeseq(!esc);
  2107. for (p = esc1; *p != '\0'; p++) {
  2108. if (*p == c) return esc2[p - esc1];
  2109. }
  2110. return 0;
  2111. }
  2112. static int mg_pass_string(const char *s, int len) {
  2113. int i;
  2114. for (i = 0; i < len; i++) {
  2115. if (s[i] == '\\' && i + 1 < len && json_esc(s[i + 1], 1)) {
  2116. i++;
  2117. } else if (s[i] == '\0') {
  2118. return MG_JSON_INVALID;
  2119. } else if (s[i] == '"') {
  2120. return i;
  2121. }
  2122. }
  2123. return MG_JSON_INVALID;
  2124. }
  2125. static double mg_atod(const char *p, int len, int *numlen) {
  2126. double d = 0.0;
  2127. int i = 0, sign = 1;
  2128. // Sign
  2129. if (i < len && *p == '-') {
  2130. sign = -1, i++;
  2131. } else if (i < len && *p == '+') {
  2132. i++;
  2133. }
  2134. // Decimal
  2135. for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
  2136. d *= 10.0;
  2137. d += p[i] - '0';
  2138. }
  2139. d *= sign;
  2140. // Fractional
  2141. if (i < len && p[i] == '.') {
  2142. double frac = 0.0, base = 0.1;
  2143. i++;
  2144. for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
  2145. frac += base * (p[i] - '0');
  2146. base /= 10.0;
  2147. }
  2148. d += frac * sign;
  2149. }
  2150. // Exponential
  2151. if (i < len && (p[i] == 'e' || p[i] == 'E')) {
  2152. int j, exp = 0, minus = 0;
  2153. i++;
  2154. if (i < len && p[i] == '-') minus = 1, i++;
  2155. if (i < len && p[i] == '+') i++;
  2156. while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
  2157. exp = exp * 10 + (p[i++] - '0');
  2158. if (minus) exp = -exp;
  2159. for (j = 0; j < exp; j++) d *= 10.0;
  2160. for (j = 0; j < -exp; j++) d /= 10.0;
  2161. }
  2162. if (numlen != NULL) *numlen = i;
  2163. return d;
  2164. }
  2165. int mg_json_get(struct mg_str json, const char *path, int *toklen) {
  2166. const char *s = json.ptr;
  2167. int len = (int) json.len;
  2168. enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE;
  2169. unsigned char nesting[MG_JSON_MAX_DEPTH];
  2170. int i = 0; // Current offset in `s`
  2171. int j = 0; // Offset in `s` we're looking for (return value)
  2172. int depth = 0; // Current depth (nesting level)
  2173. int ed = 0; // Expected depth
  2174. int pos = 1; // Current position in `path`
  2175. int ci = -1, ei = -1; // Current and expected index in array
  2176. if (toklen) *toklen = 0;
  2177. if (path[0] != '$') return MG_JSON_INVALID;
  2178. #define MG_CHECKRET(x) \
  2179. do { \
  2180. if (depth == ed && path[pos] == '\0' && ci == ei) { \
  2181. if (toklen) *toklen = i - j + 1; \
  2182. return j; \
  2183. } \
  2184. } while (0)
  2185. // In the ascii table, the distance between `[` and `]` is 2.
  2186. // Ditto for `{` and `}`. Hence +2 in the code below.
  2187. #define MG_EOO(x) \
  2188. do { \
  2189. if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND; \
  2190. if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
  2191. depth--; \
  2192. MG_CHECKRET(x); \
  2193. } while (0)
  2194. for (i = 0; i < len; i++) {
  2195. unsigned char c = ((unsigned char *) s)[i];
  2196. if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
  2197. switch (expecting) {
  2198. case S_VALUE:
  2199. // p("V %s [%.*s] %d %d %d %d\n", path, pos, path, depth, ed, ci, ei);
  2200. if (depth == ed) j = i;
  2201. if (c == '{') {
  2202. if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
  2203. if (depth == ed && path[pos] == '.' && ci == ei) {
  2204. // If we start the object, reset array indices
  2205. ed++, pos++, ci = ei = -1;
  2206. }
  2207. nesting[depth++] = c;
  2208. expecting = S_KEY;
  2209. break;
  2210. } else if (c == '[') {
  2211. if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
  2212. if (depth == ed && path[pos] == '[' && ei == ci) {
  2213. ed++, pos++, ci = 0;
  2214. for (ei = 0; path[pos] != ']' && path[pos] != '\0'; pos++) {
  2215. ei *= 10;
  2216. ei += path[pos] - '0';
  2217. }
  2218. if (path[pos] != 0) pos++;
  2219. }
  2220. nesting[depth++] = c;
  2221. break;
  2222. } else if (c == ']' && depth > 0) { // Empty array
  2223. MG_EOO(']');
  2224. } else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
  2225. i += 3;
  2226. } else if (c == 'n' && i + 3 < len && memcmp(&s[i], "null", 4) == 0) {
  2227. i += 3;
  2228. } else if (c == 'f' && i + 4 < len && memcmp(&s[i], "false", 5) == 0) {
  2229. i += 4;
  2230. } else if (c == '-' || ((c >= '0' && c <= '9'))) {
  2231. int numlen = 0;
  2232. mg_atod(&s[i], len - i, &numlen);
  2233. i += numlen - 1;
  2234. } else if (c == '"') {
  2235. int n = mg_pass_string(&s[i + 1], len - i - 1);
  2236. if (n < 0) return n;
  2237. i += n + 1;
  2238. } else {
  2239. return MG_JSON_INVALID;
  2240. }
  2241. MG_CHECKRET('V');
  2242. if (depth == ed && ei >= 0) ci++;
  2243. expecting = S_COMMA_OR_EOO;
  2244. break;
  2245. case S_KEY:
  2246. if (c == '"') {
  2247. int n = mg_pass_string(&s[i + 1], len - i - 1);
  2248. if (n < 0) return n;
  2249. if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
  2250. if (depth < ed) return MG_JSON_NOT_FOUND;
  2251. if (depth == ed && path[pos - 1] != '.') return MG_JSON_NOT_FOUND;
  2252. // printf("K %s [%.*s] [%.*s] %d %d %d\n", path, pos, path, n,
  2253. // &s[i + 1], n, depth, ed);
  2254. // NOTE(cpq): in the check sequence below is important.
  2255. // strncmp() must go first: it fails fast if the remaining length of
  2256. // the path is smaller than `n`.
  2257. if (depth == ed && path[pos - 1] == '.' &&
  2258. strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
  2259. (path[pos + n] == '\0' || path[pos + n] == '.' ||
  2260. path[pos + n] == '[')) {
  2261. pos += n;
  2262. }
  2263. i += n + 1;
  2264. expecting = S_COLON;
  2265. } else if (c == '}') { // Empty object
  2266. MG_EOO('}');
  2267. expecting = S_COMMA_OR_EOO;
  2268. } else {
  2269. return MG_JSON_INVALID;
  2270. }
  2271. break;
  2272. case S_COLON:
  2273. if (c == ':') {
  2274. expecting = S_VALUE;
  2275. } else {
  2276. return MG_JSON_INVALID;
  2277. }
  2278. break;
  2279. case S_COMMA_OR_EOO:
  2280. if (depth <= 0) {
  2281. return MG_JSON_INVALID;
  2282. } else if (c == ',') {
  2283. expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE;
  2284. } else if (c == ']' || c == '}') {
  2285. MG_EOO('O');
  2286. if (depth == ed && ei >= 0) ci++;
  2287. } else {
  2288. return MG_JSON_INVALID;
  2289. }
  2290. break;
  2291. }
  2292. }
  2293. return MG_JSON_NOT_FOUND;
  2294. }
  2295. bool mg_json_get_num(struct mg_str json, const char *path, double *v) {
  2296. int n, toklen, found = 0;
  2297. if ((n = mg_json_get(json, path, &toklen)) >= 0 &&
  2298. (json.ptr[n] == '-' || (json.ptr[n] >= '0' && json.ptr[n] <= '9'))) {
  2299. if (v != NULL) *v = mg_atod(json.ptr + n, toklen, NULL);
  2300. found = 1;
  2301. }
  2302. return found;
  2303. }
  2304. bool mg_json_get_bool(struct mg_str json, const char *path, bool *v) {
  2305. int found = 0, off = mg_json_get(json, path, NULL);
  2306. if (off >= 0 && (json.ptr[off] == 't' || json.ptr[off] == 'f')) {
  2307. if (v != NULL) *v = json.ptr[off] == 't';
  2308. found = 1;
  2309. }
  2310. return found;
  2311. }
  2312. static bool json_unescape(const char *s, size_t len, char *to, size_t n) {
  2313. size_t i, j;
  2314. for (i = 0, j = 0; i < len && j < n; i++, j++) {
  2315. if (s[i] == '\\' && i + 5 < len && s[i + 1] == 'u') {
  2316. // \uXXXX escape. We could process a simple one-byte chars
  2317. // \u00xx from the ASCII range. More complex chars would require
  2318. // dragging in a UTF8 library, which is too much for us
  2319. if (s[i + 2] != '0' || s[i + 3] != '0') return false; // Give up
  2320. ((unsigned char *) to)[j] = (unsigned char) mg_unhexn(s + i + 4, 2);
  2321. i += 5;
  2322. } else if (s[i] == '\\' && i + 1 < len) {
  2323. char c = json_esc(s[i + 1], 0);
  2324. if (c == 0) return false;
  2325. to[j] = c;
  2326. i++;
  2327. } else {
  2328. to[j] = s[i];
  2329. }
  2330. }
  2331. if (j >= n) return false;
  2332. if (n > 0) to[j] = '\0';
  2333. return true;
  2334. }
  2335. char *mg_json_get_str(struct mg_str json, const char *path) {
  2336. char *result = NULL;
  2337. int len = 0, off = mg_json_get(json, path, &len);
  2338. if (off >= 0 && len > 1 && json.ptr[off] == '"') {
  2339. if ((result = (char *) calloc(1, (size_t) len)) != NULL &&
  2340. !json_unescape(json.ptr + off + 1, (size_t) (len - 2), result,
  2341. (size_t) len)) {
  2342. free(result);
  2343. result = NULL;
  2344. }
  2345. }
  2346. return result;
  2347. }
  2348. char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) {
  2349. char *result = NULL;
  2350. int len = 0, off = mg_json_get(json, path, &len);
  2351. if (off >= 0 && json.ptr[off] == '"' && len > 1 &&
  2352. (result = (char *) calloc(1, (size_t) len)) != NULL) {
  2353. int k = mg_base64_decode(json.ptr + off + 1, len - 2, result);
  2354. if (slen != NULL) *slen = k;
  2355. }
  2356. return result;
  2357. }
  2358. char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) {
  2359. char *result = NULL;
  2360. int len = 0, off = mg_json_get(json, path, &len);
  2361. if (off >= 0 && json.ptr[off] == '"' && len > 1 &&
  2362. (result = (char *) calloc(1, (size_t) len / 2)) != NULL) {
  2363. mg_unhex(json.ptr + off + 1, (size_t) (len - 2), (uint8_t *) result);
  2364. result[len / 2 - 1] = '\0';
  2365. if (slen != NULL) *slen = len / 2 - 1;
  2366. }
  2367. return result;
  2368. }
  2369. long mg_json_get_long(struct mg_str json, const char *path, long dflt) {
  2370. double dv;
  2371. long result = dflt;
  2372. if (mg_json_get_num(json, path, &dv)) result = (long) dv;
  2373. return result;
  2374. }
  2375. #ifdef MG_ENABLE_LINES
  2376. #line 1 "src/log.c"
  2377. #endif
  2378. static int s_level = MG_LL_INFO;
  2379. static mg_pfn_t s_log_func = mg_pfn_stdout;
  2380. static void *s_log_func_param = NULL;
  2381. void mg_log_set_fn(mg_pfn_t fn, void *param) {
  2382. s_log_func = fn;
  2383. s_log_func_param = param;
  2384. }
  2385. static void logc(unsigned char c) {
  2386. s_log_func((char) c, s_log_func_param);
  2387. }
  2388. static void logs(const char *buf, size_t len) {
  2389. size_t i;
  2390. for (i = 0; i < len; i++) logc(((unsigned char *) buf)[i]);
  2391. }
  2392. void mg_log_set(int log_level) {
  2393. MG_DEBUG(("Setting log level to %d", log_level));
  2394. s_level = log_level;
  2395. }
  2396. bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
  2397. if (level <= s_level) {
  2398. const char *p = strrchr(file, '/');
  2399. char buf[41];
  2400. size_t n;
  2401. if (p == NULL) p = strrchr(file, '\\');
  2402. n = mg_snprintf(buf, sizeof(buf), "%-6llx %d %s:%d:%s", mg_millis(), level,
  2403. p == NULL ? file : p + 1, line, fname);
  2404. if (n > sizeof(buf) - 2) n = sizeof(buf) - 2;
  2405. while (n < sizeof(buf)) buf[n++] = ' ';
  2406. logs(buf, n - 1);
  2407. return true;
  2408. } else {
  2409. return false;
  2410. }
  2411. }
  2412. void mg_log(const char *fmt, ...) {
  2413. va_list ap;
  2414. va_start(ap, fmt);
  2415. mg_vxprintf(s_log_func, s_log_func_param, fmt, &ap);
  2416. va_end(ap);
  2417. logc((unsigned char) '\n');
  2418. }
  2419. static unsigned char nibble(unsigned c) {
  2420. return (unsigned char) (c < 10 ? c + '0' : c + 'W');
  2421. }
  2422. #define ISPRINT(x) ((x) >= ' ' && (x) <= '~')
  2423. void mg_hexdump(const void *buf, size_t len) {
  2424. const unsigned char *p = (const unsigned char *) buf;
  2425. unsigned char ascii[16], alen = 0;
  2426. size_t i;
  2427. for (i = 0; i < len; i++) {
  2428. if ((i % 16) == 0) {
  2429. // Print buffered ascii chars
  2430. if (i > 0) logs(" ", 2), logs((char *) ascii, 16), logc('\n'), alen = 0;
  2431. // Print hex address, then \t
  2432. logc(nibble((i >> 12) & 15)), logc(nibble((i >> 8) & 15)),
  2433. logc(nibble((i >> 4) & 15)), logc('0'), logs(" ", 3);
  2434. }
  2435. logc(nibble(p[i] >> 4)), logc(nibble(p[i] & 15)); // Two nibbles, e.g. c5
  2436. logc(' '); // Space after hex number
  2437. ascii[alen++] = ISPRINT(p[i]) ? p[i] : '.'; // Add to the ascii buf
  2438. }
  2439. while (alen < 16) logs(" ", 3), ascii[alen++] = ' ';
  2440. logs(" ", 2), logs((char *) ascii, 16), logc('\n');
  2441. }
  2442. #ifdef MG_ENABLE_LINES
  2443. #line 1 "src/md5.c"
  2444. #endif
  2445. #if defined(MG_ENABLE_MD5) && MG_ENABLE_MD5
  2446. static void mg_byte_reverse(unsigned char *buf, unsigned longs) {
  2447. if (MG_BIG_ENDIAN) {
  2448. do {
  2449. uint32_t t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
  2450. ((unsigned) buf[1] << 8 | buf[0]);
  2451. *(uint32_t *) buf = t;
  2452. buf += 4;
  2453. } while (--longs);
  2454. } else {
  2455. (void) buf, (void) longs; // Little endian. Do nothing
  2456. }
  2457. }
  2458. #define F1(x, y, z) (z ^ (x & (y ^ z)))
  2459. #define F2(x, y, z) F1(z, x, y)
  2460. #define F3(x, y, z) (x ^ y ^ z)
  2461. #define F4(x, y, z) (y ^ (x | ~z))
  2462. #define MD5STEP(f, w, x, y, z, data, s) \
  2463. (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
  2464. /*
  2465. * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
  2466. * initialization constants.
  2467. */
  2468. void mg_md5_init(mg_md5_ctx *ctx) {
  2469. ctx->buf[0] = 0x67452301;
  2470. ctx->buf[1] = 0xefcdab89;
  2471. ctx->buf[2] = 0x98badcfe;
  2472. ctx->buf[3] = 0x10325476;
  2473. ctx->bits[0] = 0;
  2474. ctx->bits[1] = 0;
  2475. }
  2476. static void mg_md5_transform(uint32_t buf[4], uint32_t const in[16]) {
  2477. uint32_t a, b, c, d;
  2478. a = buf[0];
  2479. b = buf[1];
  2480. c = buf[2];
  2481. d = buf[3];
  2482. MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  2483. MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  2484. MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  2485. MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  2486. MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  2487. MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  2488. MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  2489. MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  2490. MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  2491. MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  2492. MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  2493. MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  2494. MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  2495. MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  2496. MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  2497. MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  2498. MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  2499. MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  2500. MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  2501. MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  2502. MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  2503. MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  2504. MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  2505. MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  2506. MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  2507. MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  2508. MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  2509. MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  2510. MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  2511. MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  2512. MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  2513. MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  2514. MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  2515. MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  2516. MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  2517. MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  2518. MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  2519. MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  2520. MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  2521. MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  2522. MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  2523. MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  2524. MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  2525. MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  2526. MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  2527. MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  2528. MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  2529. MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  2530. MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  2531. MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  2532. MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  2533. MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  2534. MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  2535. MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  2536. MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  2537. MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  2538. MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  2539. MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  2540. MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  2541. MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  2542. MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  2543. MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  2544. MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  2545. MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  2546. buf[0] += a;
  2547. buf[1] += b;
  2548. buf[2] += c;
  2549. buf[3] += d;
  2550. }
  2551. void mg_md5_update(mg_md5_ctx *ctx, const unsigned char *buf, size_t len) {
  2552. uint32_t t;
  2553. t = ctx->bits[0];
  2554. if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++;
  2555. ctx->bits[1] += (uint32_t) len >> 29;
  2556. t = (t >> 3) & 0x3f;
  2557. if (t) {
  2558. unsigned char *p = (unsigned char *) ctx->in + t;
  2559. t = 64 - t;
  2560. if (len < t) {
  2561. memcpy(p, buf, len);
  2562. return;
  2563. }
  2564. memcpy(p, buf, t);
  2565. mg_byte_reverse(ctx->in, 16);
  2566. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  2567. buf += t;
  2568. len -= t;
  2569. }
  2570. while (len >= 64) {
  2571. memcpy(ctx->in, buf, 64);
  2572. mg_byte_reverse(ctx->in, 16);
  2573. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  2574. buf += 64;
  2575. len -= 64;
  2576. }
  2577. memcpy(ctx->in, buf, len);
  2578. }
  2579. void mg_md5_final(mg_md5_ctx *ctx, unsigned char digest[16]) {
  2580. unsigned count;
  2581. unsigned char *p;
  2582. uint32_t *a;
  2583. count = (ctx->bits[0] >> 3) & 0x3F;
  2584. p = ctx->in + count;
  2585. *p++ = 0x80;
  2586. count = 64 - 1 - count;
  2587. if (count < 8) {
  2588. memset(p, 0, count);
  2589. mg_byte_reverse(ctx->in, 16);
  2590. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  2591. memset(ctx->in, 0, 56);
  2592. } else {
  2593. memset(p, 0, count - 8);
  2594. }
  2595. mg_byte_reverse(ctx->in, 14);
  2596. a = (uint32_t *) ctx->in;
  2597. a[14] = ctx->bits[0];
  2598. a[15] = ctx->bits[1];
  2599. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  2600. mg_byte_reverse((unsigned char *) ctx->buf, 4);
  2601. memcpy(digest, ctx->buf, 16);
  2602. memset((char *) ctx, 0, sizeof(*ctx));
  2603. }
  2604. #endif
  2605. #ifdef MG_ENABLE_LINES
  2606. #line 1 "src/mqtt.c"
  2607. #endif
  2608. #define MQTT_CLEAN_SESSION 0x02
  2609. #define MQTT_HAS_WILL 0x04
  2610. #define MQTT_WILL_RETAIN 0x20
  2611. #define MQTT_HAS_PASSWORD 0x40
  2612. #define MQTT_HAS_USER_NAME 0x80
  2613. void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
  2614. uint32_t len) {
  2615. uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
  2616. buf[0] = (uint8_t) ((cmd << 4) | flags);
  2617. do {
  2618. *vlen = len % 0x80;
  2619. len /= 0x80;
  2620. if (len > 0) *vlen |= 0x80;
  2621. vlen++;
  2622. } while (len > 0 && vlen < &buf[sizeof(buf)]);
  2623. mg_send(c, buf, (size_t) (vlen - buf));
  2624. }
  2625. static void mg_send_u16(struct mg_connection *c, uint16_t value) {
  2626. mg_send(c, &value, sizeof(value));
  2627. }
  2628. void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
  2629. char rnd[10], client_id[21], zero = 0;
  2630. struct mg_str cid = opts->client_id;
  2631. uint32_t total_len = 7 + 1 + 2 + 2;
  2632. uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0};
  2633. if (cid.len == 0) {
  2634. mg_random(rnd, sizeof(rnd));
  2635. mg_hex(rnd, sizeof(rnd), client_id);
  2636. client_id[sizeof(client_id) - 1] = '\0';
  2637. cid = mg_str(client_id);
  2638. }
  2639. if (hdr[6] == 0) hdr[6] = 4; // If version is not set, use 4 (3.1.1)
  2640. c->is_mqtt5 = hdr[6] == 5; // Set version 5 flag
  2641. hdr[7] = (uint8_t) ((opts->will_qos & 3) << 3); // Connection flags
  2642. if (opts->user.len > 0) {
  2643. total_len += 2 + (uint32_t) opts->user.len;
  2644. hdr[7] |= MQTT_HAS_USER_NAME;
  2645. }
  2646. if (opts->pass.len > 0) {
  2647. total_len += 2 + (uint32_t) opts->pass.len;
  2648. hdr[7] |= MQTT_HAS_PASSWORD;
  2649. }
  2650. if (opts->will_topic.len > 0 && opts->will_message.len > 0) {
  2651. total_len +=
  2652. 4 + (uint32_t) opts->will_topic.len + (uint32_t) opts->will_message.len;
  2653. hdr[7] |= MQTT_HAS_WILL;
  2654. }
  2655. if (opts->clean || cid.len == 0) hdr[7] |= MQTT_CLEAN_SESSION;
  2656. if (opts->will_retain) hdr[7] |= MQTT_WILL_RETAIN;
  2657. total_len += (uint32_t) cid.len;
  2658. if (c->is_mqtt5) total_len += 1U + (hdr[7] & MQTT_HAS_WILL ? 1U : 0);
  2659. mg_mqtt_send_header(c, MQTT_CMD_CONNECT, 0, total_len);
  2660. mg_send(c, hdr, sizeof(hdr));
  2661. // keepalive == 0 means "do not disconnect us!"
  2662. mg_send_u16(c, mg_htons((uint16_t) opts->keepalive));
  2663. if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); // V5 properties
  2664. mg_send_u16(c, mg_htons((uint16_t) cid.len));
  2665. mg_send(c, cid.ptr, cid.len);
  2666. if (hdr[7] & MQTT_HAS_WILL) {
  2667. if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); // will props
  2668. mg_send_u16(c, mg_htons((uint16_t) opts->will_topic.len));
  2669. mg_send(c, opts->will_topic.ptr, opts->will_topic.len);
  2670. mg_send_u16(c, mg_htons((uint16_t) opts->will_message.len));
  2671. mg_send(c, opts->will_message.ptr, opts->will_message.len);
  2672. }
  2673. if (opts->user.len > 0) {
  2674. mg_send_u16(c, mg_htons((uint16_t) opts->user.len));
  2675. mg_send(c, opts->user.ptr, opts->user.len);
  2676. }
  2677. if (opts->pass.len > 0) {
  2678. mg_send_u16(c, mg_htons((uint16_t) opts->pass.len));
  2679. mg_send(c, opts->pass.ptr, opts->pass.len);
  2680. }
  2681. }
  2682. void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic,
  2683. struct mg_str data, int qos, bool retain) {
  2684. uint8_t flags = (uint8_t) (((qos & 3) << 1) | (retain ? 1 : 0)), zero = 0;
  2685. uint32_t len = 2 + (uint32_t) topic.len + (uint32_t) data.len;
  2686. MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) topic.len, (char *) topic.ptr,
  2687. (int) data.len, (char *) data.ptr));
  2688. if (qos > 0) len += 2;
  2689. if (c->is_mqtt5) len++;
  2690. mg_mqtt_send_header(c, MQTT_CMD_PUBLISH, flags, len);
  2691. mg_send_u16(c, mg_htons((uint16_t) topic.len));
  2692. mg_send(c, topic.ptr, topic.len);
  2693. if (qos > 0) {
  2694. if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
  2695. mg_send_u16(c, mg_htons(c->mgr->mqtt_id));
  2696. }
  2697. if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero));
  2698. mg_send(c, data.ptr, data.len);
  2699. }
  2700. void mg_mqtt_sub(struct mg_connection *c, struct mg_str topic, int qos) {
  2701. uint8_t qos_ = qos & 3, zero = 0;
  2702. uint32_t len = 2 + (uint32_t) topic.len + 2 + 1 + (c->is_mqtt5 ? 1 : 0);
  2703. mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, 2, len);
  2704. if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
  2705. mg_send_u16(c, mg_htons(c->mgr->mqtt_id));
  2706. if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero));
  2707. mg_send_u16(c, mg_htons((uint16_t) topic.len));
  2708. mg_send(c, topic.ptr, topic.len);
  2709. mg_send(c, &qos_, sizeof(qos_));
  2710. }
  2711. int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version,
  2712. struct mg_mqtt_message *m) {
  2713. uint8_t lc = 0, *p, *end;
  2714. uint32_t n = 0, len_len = 0;
  2715. memset(m, 0, sizeof(*m));
  2716. m->dgram.ptr = (char *) buf;
  2717. if (len < 2) return MQTT_INCOMPLETE;
  2718. m->cmd = (uint8_t) (buf[0] >> 4);
  2719. m->qos = (buf[0] >> 1) & 3;
  2720. n = len_len = 0;
  2721. p = (uint8_t *) buf + 1;
  2722. while ((size_t) (p - buf) < len) {
  2723. lc = *((uint8_t *) p++);
  2724. n += (uint32_t) ((lc & 0x7f) << 7 * len_len);
  2725. len_len++;
  2726. if (!(lc & 0x80)) break;
  2727. if (len_len >= 4) return MQTT_MALFORMED;
  2728. }
  2729. end = p + n;
  2730. if ((lc & 0x80) || (end > buf + len)) return MQTT_INCOMPLETE;
  2731. m->dgram.len = (size_t) (end - buf);
  2732. switch (m->cmd) {
  2733. case MQTT_CMD_CONNACK:
  2734. if (end - p < 2) return MQTT_MALFORMED;
  2735. m->ack = p[1];
  2736. break;
  2737. case MQTT_CMD_PUBACK:
  2738. case MQTT_CMD_PUBREC:
  2739. case MQTT_CMD_PUBREL:
  2740. case MQTT_CMD_PUBCOMP:
  2741. case MQTT_CMD_SUBSCRIBE:
  2742. case MQTT_CMD_SUBACK:
  2743. case MQTT_CMD_UNSUBSCRIBE:
  2744. case MQTT_CMD_UNSUBACK:
  2745. if (p + 2 > end) return MQTT_MALFORMED;
  2746. m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  2747. p += 2;
  2748. break;
  2749. case MQTT_CMD_PUBLISH: {
  2750. if (p + 2 > end) return MQTT_MALFORMED;
  2751. m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  2752. m->topic.ptr = (char *) p + 2;
  2753. p += 2 + m->topic.len;
  2754. if (p > end) return MQTT_MALFORMED;
  2755. if (m->qos > 0) {
  2756. if (p + 2 > end) return MQTT_MALFORMED;
  2757. m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
  2758. p += 2;
  2759. }
  2760. if (p > end) return MQTT_MALFORMED;
  2761. if (version == 5 && p + 2 < end) p += 1 + p[0]; // Skip options
  2762. if (p > end) return MQTT_MALFORMED;
  2763. m->data.ptr = (char *) p;
  2764. m->data.len = (size_t) (end - p);
  2765. break;
  2766. }
  2767. default:
  2768. break;
  2769. }
  2770. return MQTT_OK;
  2771. }
  2772. static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
  2773. void *fn_data) {
  2774. if (ev == MG_EV_READ) {
  2775. for (;;) {
  2776. uint8_t version = c->is_mqtt5 ? 5 : 4;
  2777. struct mg_mqtt_message mm;
  2778. int rc = mg_mqtt_parse(c->recv.buf, c->recv.len, version, &mm);
  2779. if (rc == MQTT_MALFORMED) {
  2780. MG_ERROR(("%lu MQTT malformed message", c->id));
  2781. c->is_closing = 1;
  2782. break;
  2783. } else if (rc == MQTT_OK) {
  2784. MG_VERBOSE(("%lu MQTT CMD %d len %d [%.*s]", c->id, mm.cmd,
  2785. (int) mm.dgram.len, (int) mm.data.len, mm.data.ptr));
  2786. switch (mm.cmd) {
  2787. case MQTT_CMD_CONNACK:
  2788. mg_call(c, MG_EV_MQTT_OPEN, &mm.ack);
  2789. if (mm.ack == 0) {
  2790. MG_DEBUG(("%lu Connected", c->id));
  2791. } else {
  2792. MG_ERROR(("%lu MQTT auth failed, code %d", c->id, mm.ack));
  2793. c->is_closing = 1;
  2794. }
  2795. break;
  2796. case MQTT_CMD_PUBLISH: {
  2797. MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) mm.topic.len,
  2798. mm.topic.ptr, (int) mm.data.len, mm.data.ptr));
  2799. if (mm.qos > 0) {
  2800. uint16_t id = mg_htons(mm.id);
  2801. mg_mqtt_send_header(c, MQTT_CMD_PUBACK, 0, sizeof(id));
  2802. mg_send(c, &id, sizeof(id));
  2803. }
  2804. mg_call(c, MG_EV_MQTT_MSG, &mm);
  2805. break;
  2806. }
  2807. }
  2808. mg_call(c, MG_EV_MQTT_CMD, &mm);
  2809. mg_iobuf_del(&c->recv, 0, mm.dgram.len);
  2810. } else {
  2811. break;
  2812. }
  2813. }
  2814. }
  2815. (void) ev_data;
  2816. (void) fn_data;
  2817. }
  2818. void mg_mqtt_ping(struct mg_connection *nc) {
  2819. mg_mqtt_send_header(nc, MQTT_CMD_PINGREQ, 0, 0);
  2820. }
  2821. void mg_mqtt_pong(struct mg_connection *nc) {
  2822. mg_mqtt_send_header(nc, MQTT_CMD_PINGRESP, 0, 0);
  2823. }
  2824. void mg_mqtt_disconnect(struct mg_connection *nc) {
  2825. mg_mqtt_send_header(nc, MQTT_CMD_DISCONNECT, 0, 0);
  2826. }
  2827. struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url,
  2828. const struct mg_mqtt_opts *opts,
  2829. mg_event_handler_t fn, void *fn_data) {
  2830. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  2831. if (c != NULL) {
  2832. struct mg_mqtt_opts empty;
  2833. memset(&empty, 0, sizeof(empty));
  2834. mg_mqtt_login(c, opts == NULL ? &empty : opts);
  2835. c->pfn = mqtt_cb;
  2836. }
  2837. return c;
  2838. }
  2839. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  2840. mg_event_handler_t fn, void *fn_data) {
  2841. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  2842. if (c != NULL) c->pfn = mqtt_cb, c->pfn_data = mgr;
  2843. return c;
  2844. }
  2845. #ifdef MG_ENABLE_LINES
  2846. #line 1 "src/net.c"
  2847. #endif
  2848. size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list *ap) {
  2849. size_t old = c->send.len;
  2850. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  2851. return c->send.len - old;
  2852. }
  2853. size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
  2854. size_t len = 0;
  2855. va_list ap;
  2856. va_start(ap, fmt);
  2857. len = mg_vprintf(c, fmt, &ap);
  2858. va_end(ap);
  2859. return len;
  2860. }
  2861. static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
  2862. if (mg_vcasecmp(&str, "localhost") != 0) return false;
  2863. addr->ip = mg_htonl(0x7f000001);
  2864. addr->is_ip6 = false;
  2865. return true;
  2866. }
  2867. static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
  2868. if (str.len > 0) return false;
  2869. addr->ip = 0;
  2870. addr->is_ip6 = false;
  2871. return true;
  2872. }
  2873. static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
  2874. uint8_t data[4] = {0, 0, 0, 0};
  2875. size_t i, num_dots = 0;
  2876. for (i = 0; i < str.len; i++) {
  2877. if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
  2878. int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
  2879. if (octet > 255) return false;
  2880. data[num_dots] = (uint8_t) octet;
  2881. } else if (str.ptr[i] == '.') {
  2882. if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
  2883. num_dots++;
  2884. } else {
  2885. return false;
  2886. }
  2887. }
  2888. if (num_dots != 3 || str.ptr[i - 1] == '.') return false;
  2889. memcpy(&addr->ip, data, sizeof(data));
  2890. addr->is_ip6 = false;
  2891. return true;
  2892. }
  2893. static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
  2894. int i;
  2895. if (str.len < 14) return false;
  2896. if (str.ptr[0] != ':' || str.ptr[1] != ':' || str.ptr[6] != ':') return false;
  2897. for (i = 2; i < 6; i++) {
  2898. if (str.ptr[i] != 'f' && str.ptr[i] != 'F') return false;
  2899. }
  2900. if (!mg_aton4(mg_str_n(&str.ptr[7], str.len - 7), addr)) return false;
  2901. memset(addr->ip6, 0, sizeof(addr->ip6));
  2902. addr->ip6[10] = addr->ip6[11] = 255;
  2903. memcpy(&addr->ip6[12], &addr->ip, 4);
  2904. addr->is_ip6 = true;
  2905. return true;
  2906. }
  2907. static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
  2908. size_t i, j = 0, n = 0, dc = 42;
  2909. if (str.len > 2 && str.ptr[0] == '[') str.ptr++, str.len -= 2;
  2910. if (mg_v4mapped(str, addr)) return true;
  2911. for (i = 0; i < str.len; i++) {
  2912. if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') ||
  2913. (str.ptr[i] >= 'a' && str.ptr[i] <= 'f') ||
  2914. (str.ptr[i] >= 'A' && str.ptr[i] <= 'F')) {
  2915. unsigned long val;
  2916. if (i > j + 3) return false;
  2917. // MG_DEBUG(("%zu %zu [%.*s]", i, j, (int) (i - j + 1), &str.ptr[j]));
  2918. val = mg_unhexn(&str.ptr[j], i - j + 1);
  2919. addr->ip6[n] = (uint8_t) ((val >> 8) & 255);
  2920. addr->ip6[n + 1] = (uint8_t) (val & 255);
  2921. } else if (str.ptr[i] == ':') {
  2922. j = i + 1;
  2923. if (i > 0 && str.ptr[i - 1] == ':') {
  2924. dc = n; // Double colon
  2925. if (i > 1 && str.ptr[i - 2] == ':') return false;
  2926. } else if (i > 0) {
  2927. n += 2;
  2928. }
  2929. if (n > 14) return false;
  2930. addr->ip6[n] = addr->ip6[n + 1] = 0; // For trailing ::
  2931. } else {
  2932. return false;
  2933. }
  2934. }
  2935. if (n < 14 && dc == 42) return false;
  2936. if (n < 14) {
  2937. memmove(&addr->ip6[dc + (14 - n)], &addr->ip6[dc], n - dc + 2);
  2938. memset(&addr->ip6[dc], 0, 14 - n);
  2939. }
  2940. addr->is_ip6 = true;
  2941. return true;
  2942. }
  2943. bool mg_aton(struct mg_str str, struct mg_addr *addr) {
  2944. // MG_INFO(("[%.*s]", (int) str.len, str.ptr));
  2945. return mg_atone(str, addr) || mg_atonl(str, addr) || mg_aton4(str, addr) ||
  2946. mg_aton6(str, addr);
  2947. }
  2948. struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) {
  2949. struct mg_connection *c =
  2950. (struct mg_connection *) calloc(1, sizeof(*c) + mgr->extraconnsize);
  2951. if (c != NULL) {
  2952. c->mgr = mgr;
  2953. c->send.align = c->recv.align = MG_IO_SIZE;
  2954. c->id = ++mgr->nextid;
  2955. }
  2956. return c;
  2957. }
  2958. void mg_close_conn(struct mg_connection *c) {
  2959. mg_resolve_cancel(c); // Close any pending DNS query
  2960. LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
  2961. if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
  2962. if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
  2963. // Order of operations is important. `MG_EV_CLOSE` event must be fired
  2964. // before we deallocate received data, see #1331
  2965. mg_call(c, MG_EV_CLOSE, NULL);
  2966. MG_DEBUG(("%lu %p closed", c->id, c->fd));
  2967. mg_tls_free(c);
  2968. mg_iobuf_free(&c->recv);
  2969. mg_iobuf_free(&c->send);
  2970. memset(c, 0, sizeof(*c));
  2971. free(c);
  2972. }
  2973. struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
  2974. mg_event_handler_t fn, void *fn_data) {
  2975. struct mg_connection *c = NULL;
  2976. if (url == NULL || url[0] == '\0') {
  2977. MG_ERROR(("null url"));
  2978. } else if ((c = mg_alloc_conn(mgr)) == NULL) {
  2979. MG_ERROR(("OOM"));
  2980. } else {
  2981. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  2982. c->is_udp = (strncmp(url, "udp:", 4) == 0);
  2983. c->fd = (void *) (size_t) MG_INVALID_SOCKET;
  2984. c->fn = fn;
  2985. c->is_client = true;
  2986. c->fn_data = fn_data;
  2987. MG_DEBUG(("%lu %p %s", c->id, c->fd, url));
  2988. mg_call(c, MG_EV_OPEN, NULL);
  2989. mg_resolve(c, url);
  2990. }
  2991. return c;
  2992. }
  2993. struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
  2994. mg_event_handler_t fn, void *fn_data) {
  2995. struct mg_connection *c = NULL;
  2996. if ((c = mg_alloc_conn(mgr)) == NULL) {
  2997. MG_ERROR(("OOM %s", url));
  2998. } else if (!mg_open_listener(c, url)) {
  2999. MG_ERROR(("Failed: %s, errno %d", url, errno));
  3000. free(c);
  3001. c = NULL;
  3002. } else {
  3003. c->is_listening = 1;
  3004. c->is_udp = strncmp(url, "udp:", 4) == 0;
  3005. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  3006. c->fn = fn;
  3007. c->fn_data = fn_data;
  3008. mg_call(c, MG_EV_OPEN, NULL);
  3009. MG_DEBUG(("%lu %p %s", c->id, c->fd, url));
  3010. }
  3011. return c;
  3012. }
  3013. struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
  3014. mg_event_handler_t fn, void *fn_data) {
  3015. struct mg_connection *c = mg_alloc_conn(mgr);
  3016. if (c != NULL) {
  3017. c->fd = (void *) (size_t) fd;
  3018. c->fn = fn;
  3019. c->fn_data = fn_data;
  3020. MG_EPOLL_ADD(c);
  3021. mg_call(c, MG_EV_OPEN, NULL);
  3022. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  3023. }
  3024. return c;
  3025. }
  3026. struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
  3027. unsigned flags, void (*fn)(void *), void *arg) {
  3028. struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
  3029. if (t != NULL) {
  3030. mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
  3031. t->id = mgr->timerid++;
  3032. }
  3033. return t;
  3034. }
  3035. void mg_mgr_free(struct mg_mgr *mgr) {
  3036. struct mg_connection *c;
  3037. struct mg_timer *tmp, *t = mgr->timers;
  3038. while (t != NULL) tmp = t->next, free(t), t = tmp;
  3039. mgr->timers = NULL; // Important. Next call to poll won't touch timers
  3040. for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
  3041. mg_mgr_poll(mgr, 0);
  3042. #if MG_ENABLE_FREERTOS_TCP
  3043. FreeRTOS_DeleteSocketSet(mgr->ss);
  3044. #endif
  3045. MG_DEBUG(("All connections closed"));
  3046. #if MG_ENABLE_EPOLL
  3047. if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
  3048. #endif
  3049. }
  3050. void mg_mgr_init(struct mg_mgr *mgr) {
  3051. memset(mgr, 0, sizeof(*mgr));
  3052. #if MG_ENABLE_EPOLL
  3053. if ((mgr->epoll_fd = epoll_create1(0)) < 0) MG_ERROR(("epoll: %d", errno));
  3054. #else
  3055. mgr->epoll_fd = -1;
  3056. #endif
  3057. #if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  3058. // clang-format off
  3059. { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
  3060. // clang-format on
  3061. #elif MG_ENABLE_FREERTOS_TCP
  3062. mgr->ss = FreeRTOS_CreateSocketSet();
  3063. #elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
  3064. // Ignore SIGPIPE signal, so if client cancels the request, it
  3065. // won't kill the whole process.
  3066. signal(SIGPIPE, SIG_IGN);
  3067. #endif
  3068. mgr->dnstimeout = 3000;
  3069. mgr->dns4.url = "udp://8.8.8.8:53";
  3070. mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
  3071. }
  3072. #ifdef MG_ENABLE_LINES
  3073. #line 1 "src/printf.c"
  3074. #endif
  3075. size_t mg_queue_vprintf(struct mg_queue *q, const char *fmt, va_list *ap) {
  3076. size_t len = mg_snprintf(NULL, 0, fmt, ap);
  3077. char *buf;
  3078. if (len == 0 || mg_queue_book(q, &buf, len + 1) < len + 1) {
  3079. len = 0; // Nah. Not enough space
  3080. } else {
  3081. len = mg_vsnprintf((char *) buf, len + 1, fmt, ap);
  3082. mg_queue_add(q, len);
  3083. }
  3084. return len;
  3085. }
  3086. size_t mg_queue_printf(struct mg_queue *q, const char *fmt, ...) {
  3087. va_list ap;
  3088. size_t len;
  3089. va_start(ap, fmt);
  3090. len = mg_queue_vprintf(q, fmt, &ap);
  3091. va_end(ap);
  3092. return len;
  3093. }
  3094. static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
  3095. struct mg_iobuf *io = (struct mg_iobuf *) param;
  3096. if (expand && io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
  3097. if (io->len + 2 <= io->size) {
  3098. io->buf[io->len++] = (uint8_t) ch;
  3099. io->buf[io->len] = 0;
  3100. } else if (io->len < io->size) {
  3101. io->buf[io->len++] = 0; // Guarantee to 0-terminate
  3102. }
  3103. }
  3104. static void mg_putchar_iobuf_static(char ch, void *param) {
  3105. mg_pfn_iobuf_private(ch, param, false);
  3106. }
  3107. void mg_pfn_iobuf(char ch, void *param) {
  3108. mg_pfn_iobuf_private(ch, param, true);
  3109. }
  3110. size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
  3111. struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
  3112. size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
  3113. if (n < len) buf[n] = '\0';
  3114. return n;
  3115. }
  3116. size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
  3117. va_list ap;
  3118. size_t n;
  3119. va_start(ap, fmt);
  3120. n = mg_vsnprintf(buf, len, fmt, &ap);
  3121. va_end(ap);
  3122. return n;
  3123. }
  3124. char *mg_vmprintf(const char *fmt, va_list *ap) {
  3125. struct mg_iobuf io = {0, 0, 0, 256};
  3126. mg_vxprintf(mg_pfn_iobuf, &io, fmt, ap);
  3127. return (char *) io.buf;
  3128. }
  3129. char *mg_mprintf(const char *fmt, ...) {
  3130. char *s;
  3131. va_list ap;
  3132. va_start(ap, fmt);
  3133. s = mg_vmprintf(fmt, &ap);
  3134. va_end(ap);
  3135. return s;
  3136. }
  3137. void mg_pfn_stdout(char c, void *param) {
  3138. putchar(c);
  3139. (void) param;
  3140. }
  3141. static size_t print_ip4(void (*out)(char, void *), void *arg, uint8_t *p) {
  3142. return mg_xprintf(out, arg, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  3143. }
  3144. static size_t print_ip6(void (*out)(char, void *), void *arg, uint16_t *p) {
  3145. return mg_xprintf(out, arg, "[%x:%x:%x:%x:%x:%x:%x:%x]", mg_ntohs(p[0]),
  3146. mg_ntohs(p[1]), mg_ntohs(p[2]), mg_ntohs(p[3]),
  3147. mg_ntohs(p[4]), mg_ntohs(p[5]), mg_ntohs(p[6]),
  3148. mg_ntohs(p[7]));
  3149. }
  3150. size_t mg_print_ip4(void (*out)(char, void *), void *arg, va_list *ap) {
  3151. uint8_t *p = va_arg(*ap, uint8_t *);
  3152. return print_ip4(out, arg, p);
  3153. }
  3154. size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap) {
  3155. uint16_t *p = va_arg(*ap, uint16_t *);
  3156. return print_ip6(out, arg, p);
  3157. }
  3158. size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap) {
  3159. struct mg_addr *addr = va_arg(*ap, struct mg_addr *);
  3160. if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->ip6);
  3161. return print_ip4(out, arg, (uint8_t *) &addr->ip);
  3162. }
  3163. size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap) {
  3164. struct mg_addr *a = va_arg(*ap, struct mg_addr *);
  3165. return mg_xprintf(out, arg, "%M:%hu", mg_print_ip, a, mg_ntohs(a->port));
  3166. }
  3167. size_t mg_print_mac(void (*out)(char, void *), void *arg, va_list *ap) {
  3168. uint8_t *p = va_arg(*ap, uint8_t *);
  3169. return mg_xprintf(out, arg, "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2],
  3170. p[3], p[4], p[5]);
  3171. }
  3172. static char mg_esc(int c, bool esc) {
  3173. const char *p, *esc1 = "\b\f\n\r\t\\\"", *esc2 = "bfnrt\\\"";
  3174. for (p = esc ? esc1 : esc2; *p != '\0'; p++) {
  3175. if (*p == c) return esc ? esc2[p - esc1] : esc1[p - esc2];
  3176. }
  3177. return 0;
  3178. }
  3179. static char mg_escape(int c) {
  3180. return mg_esc(c, true);
  3181. }
  3182. static size_t qcpy(void (*out)(char, void *), void *ptr, char *buf,
  3183. size_t len) {
  3184. size_t i = 0, extra = 0;
  3185. for (i = 0; i < len && buf[i] != '\0'; i++) {
  3186. char c = mg_escape(buf[i]);
  3187. if (c) {
  3188. out('\\', ptr), out(c, ptr), extra++;
  3189. } else {
  3190. out(buf[i], ptr);
  3191. }
  3192. }
  3193. return i + extra;
  3194. }
  3195. static size_t bcpy(void (*out)(char, void *), void *arg, uint8_t *buf,
  3196. size_t len) {
  3197. size_t i, j, n = 0;
  3198. const char *t =
  3199. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  3200. for (i = 0; i < len; i += 3) {
  3201. uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0,
  3202. c3 = i + 2 < len ? buf[i + 2] : 0;
  3203. char tmp[4] = {t[c1 >> 2], t[(c1 & 3) << 4 | (c2 >> 4)], '=', '='};
  3204. if (i + 1 < len) tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)];
  3205. if (i + 2 < len) tmp[3] = t[c3 & 63];
  3206. for (j = 0; j < sizeof(tmp) && tmp[j] != '\0'; j++) out(tmp[j], arg);
  3207. n += j;
  3208. }
  3209. return n;
  3210. }
  3211. size_t mg_print_hex(void (*out)(char, void *), void *arg, va_list *ap) {
  3212. size_t bl = (size_t) va_arg(*ap, int);
  3213. uint8_t *p = va_arg(*ap, uint8_t *);
  3214. const char *hex = "0123456789abcdef";
  3215. size_t j;
  3216. for (j = 0; j < bl; j++) {
  3217. out(hex[(p[j] >> 4) & 0x0F], arg);
  3218. out(hex[p[j] & 0x0F], arg);
  3219. }
  3220. return 2 * bl;
  3221. }
  3222. size_t mg_print_base64(void (*out)(char, void *), void *arg, va_list *ap) {
  3223. size_t len = (size_t) va_arg(*ap, int);
  3224. uint8_t *buf = va_arg(*ap, uint8_t *);
  3225. return bcpy(out, arg, buf, len);
  3226. }
  3227. size_t mg_print_esc(void (*out)(char, void *), void *arg, va_list *ap) {
  3228. size_t len = (size_t) va_arg(*ap, int);
  3229. char *p = va_arg(*ap, char *);
  3230. if (len == 0) len = p == NULL ? 0 : strlen(p);
  3231. return qcpy(out, arg, p, len);
  3232. }
  3233. #ifdef MG_ENABLE_LINES
  3234. #line 1 "src/queue.c"
  3235. #endif
  3236. #if defined(__GNUC__) || defined(__clang__)
  3237. #define MG_MEMORY_BARRIER() __sync_synchronize()
  3238. #elif defined(_MSC_VER) && _MSC_VER >= 1700
  3239. #define MG_MEMORY_BARRIER() MemoryBarrier()
  3240. #elif !defined(MG_MEMORY_BARRIER)
  3241. #define MG_MEMORY_BARRIER()
  3242. #endif
  3243. // Every message in a queue is prepended by a 32-bit message length (ML).
  3244. // If ML is 0, then it is the end, and reader must wrap to the beginning.
  3245. //
  3246. // Queue when q->tail <= q->head:
  3247. // |----- free -----| ML | message1 | ML | message2 | ----- free ------|
  3248. // ^ ^ ^ ^
  3249. // buf tail head len
  3250. //
  3251. // Queue when q->tail > q->head:
  3252. // | ML | message2 |----- free ------| ML | message1 | 0 |---- free ----|
  3253. // ^ ^ ^ ^
  3254. // buf head tail len
  3255. void mg_queue_init(struct mg_queue *q, char *buf, size_t size) {
  3256. q->size = size;
  3257. q->buf = buf;
  3258. q->head = q->tail = 0;
  3259. }
  3260. static size_t mg_queue_read_len(struct mg_queue *q) {
  3261. uint32_t n = 0;
  3262. MG_MEMORY_BARRIER();
  3263. memcpy(&n, q->buf + q->tail, sizeof(n));
  3264. assert(q->tail + n + sizeof(n) <= q->size);
  3265. return n;
  3266. }
  3267. static void mg_queue_write_len(struct mg_queue *q, size_t len) {
  3268. uint32_t n = (uint32_t) len;
  3269. memcpy(q->buf + q->head, &n, sizeof(n));
  3270. MG_MEMORY_BARRIER();
  3271. }
  3272. size_t mg_queue_book(struct mg_queue *q, char **buf, size_t len) {
  3273. size_t space = 0, hs = sizeof(uint32_t) * 2; // *2 is for the 0 marker
  3274. if (q->head >= q->tail && q->head + len + hs <= q->size) {
  3275. space = q->size - q->head - hs; // There is enough space
  3276. } else if (q->head >= q->tail && q->tail > hs) {
  3277. mg_queue_write_len(q, 0); // Not enough space ahead
  3278. q->head = 0; // Wrap head to the beginning
  3279. }
  3280. if (q->head + hs + len < q->tail) space = q->tail - q->head - hs;
  3281. if (buf != NULL) *buf = q->buf + q->head + sizeof(uint32_t);
  3282. return space;
  3283. }
  3284. size_t mg_queue_next(struct mg_queue *q, char **buf) {
  3285. size_t len = 0;
  3286. if (q->tail != q->head) {
  3287. len = mg_queue_read_len(q);
  3288. if (len == 0) { // Zero (head wrapped) ?
  3289. q->tail = 0; // Reset tail to the start
  3290. if (q->head > q->tail) len = mg_queue_read_len(q); // Read again
  3291. }
  3292. }
  3293. if (buf != NULL) *buf = q->buf + q->tail + sizeof(uint32_t);
  3294. assert(q->tail + len <= q->size);
  3295. return len;
  3296. }
  3297. void mg_queue_add(struct mg_queue *q, size_t len) {
  3298. assert(len > 0);
  3299. mg_queue_write_len(q, len);
  3300. assert(q->head + sizeof(uint32_t) * 2 + len <= q->size);
  3301. q->head += len + sizeof(uint32_t);
  3302. }
  3303. void mg_queue_del(struct mg_queue *q, size_t len) {
  3304. q->tail += len + sizeof(uint32_t);
  3305. assert(q->tail + sizeof(uint32_t) <= q->size);
  3306. }
  3307. #ifdef MG_ENABLE_LINES
  3308. #line 1 "src/rpc.c"
  3309. #endif
  3310. void mg_rpc_add(struct mg_rpc **head, struct mg_str method,
  3311. void (*fn)(struct mg_rpc_req *), void *fn_data) {
  3312. struct mg_rpc *rpc = (struct mg_rpc *) calloc(1, sizeof(*rpc));
  3313. if (rpc != NULL) {
  3314. rpc->method = mg_strdup(method), rpc->fn = fn, rpc->fn_data = fn_data;
  3315. rpc->next = *head, *head = rpc;
  3316. }
  3317. }
  3318. void mg_rpc_del(struct mg_rpc **head, void (*fn)(struct mg_rpc_req *)) {
  3319. struct mg_rpc *r;
  3320. while ((r = *head) != NULL) {
  3321. if (r->fn == fn || fn == NULL) {
  3322. *head = r->next;
  3323. free((void *) r->method.ptr);
  3324. free(r);
  3325. } else {
  3326. head = &(*head)->next;
  3327. }
  3328. }
  3329. }
  3330. static void mg_rpc_call(struct mg_rpc_req *r, struct mg_str method) {
  3331. struct mg_rpc *h = r->head == NULL ? NULL : *r->head;
  3332. while (h != NULL && !mg_match(method, h->method, NULL)) h = h->next;
  3333. if (h != NULL) {
  3334. r->rpc = h;
  3335. h->fn(r);
  3336. } else {
  3337. mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) method.len, method.ptr);
  3338. }
  3339. }
  3340. void mg_rpc_process(struct mg_rpc_req *r) {
  3341. int len, off = mg_json_get(r->frame, "$.method", &len);
  3342. if (off > 0 && r->frame.ptr[off] == '"') {
  3343. struct mg_str method = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2);
  3344. mg_rpc_call(r, method);
  3345. } else if ((off = mg_json_get(r->frame, "$.result", &len)) > 0 ||
  3346. (off = mg_json_get(r->frame, "$.error", &len)) > 0) {
  3347. mg_rpc_call(r, mg_str("")); // JSON response! call "" method handler
  3348. } else {
  3349. mg_rpc_err(r, -32700, "%m", mg_print_esc, (int) r->frame.len,
  3350. r->frame.ptr); // Invalid
  3351. }
  3352. }
  3353. void mg_rpc_vok(struct mg_rpc_req *r, const char *fmt, va_list *ap) {
  3354. int len, off = mg_json_get(r->frame, "$.id", &len);
  3355. if (off > 0) {
  3356. mg_xprintf(r->pfn, r->pfn_data, "{%m:%.*s,%m:", mg_print_esc, 0, "id", len,
  3357. &r->frame.ptr[off], mg_print_esc, 0, "result");
  3358. mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
  3359. mg_xprintf(r->pfn, r->pfn_data, "}");
  3360. }
  3361. }
  3362. void mg_rpc_ok(struct mg_rpc_req *r, const char *fmt, ...) {
  3363. va_list ap;
  3364. va_start(ap, fmt);
  3365. mg_rpc_vok(r, fmt, &ap);
  3366. va_end(ap);
  3367. }
  3368. void mg_rpc_verr(struct mg_rpc_req *r, int code, const char *fmt, va_list *ap) {
  3369. int len, off = mg_json_get(r->frame, "$.id", &len);
  3370. mg_xprintf(r->pfn, r->pfn_data, "{");
  3371. if (off > 0) {
  3372. mg_xprintf(r->pfn, r->pfn_data, "%m:%.*s,", mg_print_esc, 0, "id", len,
  3373. &r->frame.ptr[off]);
  3374. }
  3375. mg_xprintf(r->pfn, r->pfn_data, "%m:{%m:%d,%m:", mg_print_esc, 0, "error",
  3376. mg_print_esc, 0, "code", code, mg_print_esc, 0, "message");
  3377. mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
  3378. mg_xprintf(r->pfn, r->pfn_data, "}}");
  3379. }
  3380. void mg_rpc_err(struct mg_rpc_req *r, int code, const char *fmt, ...) {
  3381. va_list ap;
  3382. va_start(ap, fmt);
  3383. mg_rpc_verr(r, code, fmt, &ap);
  3384. va_end(ap);
  3385. }
  3386. static size_t print_methods(mg_pfn_t pfn, void *pfn_data, va_list *ap) {
  3387. struct mg_rpc *h, **head = (struct mg_rpc **) va_arg(*ap, void **);
  3388. size_t len = 0;
  3389. for (h = *head; h != NULL; h = h->next) {
  3390. if (h->method.len == 0) continue; // Ignore response handler
  3391. len += mg_xprintf(pfn, pfn_data, "%s%m", h == *head ? "" : ",",
  3392. mg_print_esc, (int) h->method.len, h->method.ptr);
  3393. }
  3394. return len;
  3395. }
  3396. void mg_rpc_list(struct mg_rpc_req *r) {
  3397. mg_rpc_ok(r, "[%M]", print_methods, r->head);
  3398. }
  3399. #ifdef MG_ENABLE_LINES
  3400. #line 1 "src/sha1.c"
  3401. #endif
  3402. /* Copyright(c) By Steve Reid <steve@edmweb.com> */
  3403. /* 100% Public Domain */
  3404. union char64long16 {
  3405. unsigned char c[64];
  3406. uint32_t l[16];
  3407. };
  3408. #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  3409. static uint32_t blk0(union char64long16 *block, int i) {
  3410. if (MG_BIG_ENDIAN) {
  3411. } else {
  3412. block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) |
  3413. (rol(block->l[i], 8) & 0x00FF00FF);
  3414. }
  3415. return block->l[i];
  3416. }
  3417. /* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */
  3418. #undef blk
  3419. #undef R0
  3420. #undef R1
  3421. #undef R2
  3422. #undef R3
  3423. #undef R4
  3424. #define blk(i) \
  3425. (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \
  3426. block->l[(i + 2) & 15] ^ block->l[i & 15], \
  3427. 1))
  3428. #define R0(v, w, x, y, z, i) \
  3429. z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \
  3430. w = rol(w, 30);
  3431. #define R1(v, w, x, y, z, i) \
  3432. z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
  3433. w = rol(w, 30);
  3434. #define R2(v, w, x, y, z, i) \
  3435. z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
  3436. w = rol(w, 30);
  3437. #define R3(v, w, x, y, z, i) \
  3438. z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
  3439. w = rol(w, 30);
  3440. #define R4(v, w, x, y, z, i) \
  3441. z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
  3442. w = rol(w, 30);
  3443. static void mg_sha1_transform(uint32_t state[5],
  3444. const unsigned char *buffer) {
  3445. uint32_t a, b, c, d, e;
  3446. union char64long16 block[1];
  3447. memcpy(block, buffer, 64);
  3448. a = state[0];
  3449. b = state[1];
  3450. c = state[2];
  3451. d = state[3];
  3452. e = state[4];
  3453. R0(a, b, c, d, e, 0);
  3454. R0(e, a, b, c, d, 1);
  3455. R0(d, e, a, b, c, 2);
  3456. R0(c, d, e, a, b, 3);
  3457. R0(b, c, d, e, a, 4);
  3458. R0(a, b, c, d, e, 5);
  3459. R0(e, a, b, c, d, 6);
  3460. R0(d, e, a, b, c, 7);
  3461. R0(c, d, e, a, b, 8);
  3462. R0(b, c, d, e, a, 9);
  3463. R0(a, b, c, d, e, 10);
  3464. R0(e, a, b, c, d, 11);
  3465. R0(d, e, a, b, c, 12);
  3466. R0(c, d, e, a, b, 13);
  3467. R0(b, c, d, e, a, 14);
  3468. R0(a, b, c, d, e, 15);
  3469. R1(e, a, b, c, d, 16);
  3470. R1(d, e, a, b, c, 17);
  3471. R1(c, d, e, a, b, 18);
  3472. R1(b, c, d, e, a, 19);
  3473. R2(a, b, c, d, e, 20);
  3474. R2(e, a, b, c, d, 21);
  3475. R2(d, e, a, b, c, 22);
  3476. R2(c, d, e, a, b, 23);
  3477. R2(b, c, d, e, a, 24);
  3478. R2(a, b, c, d, e, 25);
  3479. R2(e, a, b, c, d, 26);
  3480. R2(d, e, a, b, c, 27);
  3481. R2(c, d, e, a, b, 28);
  3482. R2(b, c, d, e, a, 29);
  3483. R2(a, b, c, d, e, 30);
  3484. R2(e, a, b, c, d, 31);
  3485. R2(d, e, a, b, c, 32);
  3486. R2(c, d, e, a, b, 33);
  3487. R2(b, c, d, e, a, 34);
  3488. R2(a, b, c, d, e, 35);
  3489. R2(e, a, b, c, d, 36);
  3490. R2(d, e, a, b, c, 37);
  3491. R2(c, d, e, a, b, 38);
  3492. R2(b, c, d, e, a, 39);
  3493. R3(a, b, c, d, e, 40);
  3494. R3(e, a, b, c, d, 41);
  3495. R3(d, e, a, b, c, 42);
  3496. R3(c, d, e, a, b, 43);
  3497. R3(b, c, d, e, a, 44);
  3498. R3(a, b, c, d, e, 45);
  3499. R3(e, a, b, c, d, 46);
  3500. R3(d, e, a, b, c, 47);
  3501. R3(c, d, e, a, b, 48);
  3502. R3(b, c, d, e, a, 49);
  3503. R3(a, b, c, d, e, 50);
  3504. R3(e, a, b, c, d, 51);
  3505. R3(d, e, a, b, c, 52);
  3506. R3(c, d, e, a, b, 53);
  3507. R3(b, c, d, e, a, 54);
  3508. R3(a, b, c, d, e, 55);
  3509. R3(e, a, b, c, d, 56);
  3510. R3(d, e, a, b, c, 57);
  3511. R3(c, d, e, a, b, 58);
  3512. R3(b, c, d, e, a, 59);
  3513. R4(a, b, c, d, e, 60);
  3514. R4(e, a, b, c, d, 61);
  3515. R4(d, e, a, b, c, 62);
  3516. R4(c, d, e, a, b, 63);
  3517. R4(b, c, d, e, a, 64);
  3518. R4(a, b, c, d, e, 65);
  3519. R4(e, a, b, c, d, 66);
  3520. R4(d, e, a, b, c, 67);
  3521. R4(c, d, e, a, b, 68);
  3522. R4(b, c, d, e, a, 69);
  3523. R4(a, b, c, d, e, 70);
  3524. R4(e, a, b, c, d, 71);
  3525. R4(d, e, a, b, c, 72);
  3526. R4(c, d, e, a, b, 73);
  3527. R4(b, c, d, e, a, 74);
  3528. R4(a, b, c, d, e, 75);
  3529. R4(e, a, b, c, d, 76);
  3530. R4(d, e, a, b, c, 77);
  3531. R4(c, d, e, a, b, 78);
  3532. R4(b, c, d, e, a, 79);
  3533. state[0] += a;
  3534. state[1] += b;
  3535. state[2] += c;
  3536. state[3] += d;
  3537. state[4] += e;
  3538. /* Erase working structures. The order of operations is important,
  3539. * used to ensure that compiler doesn't optimize those out. */
  3540. memset(block, 0, sizeof(block));
  3541. a = b = c = d = e = 0;
  3542. (void) a;
  3543. (void) b;
  3544. (void) c;
  3545. (void) d;
  3546. (void) e;
  3547. }
  3548. void mg_sha1_init(mg_sha1_ctx *context) {
  3549. context->state[0] = 0x67452301;
  3550. context->state[1] = 0xEFCDAB89;
  3551. context->state[2] = 0x98BADCFE;
  3552. context->state[3] = 0x10325476;
  3553. context->state[4] = 0xC3D2E1F0;
  3554. context->count[0] = context->count[1] = 0;
  3555. }
  3556. void mg_sha1_update(mg_sha1_ctx *context, const unsigned char *data,
  3557. size_t len) {
  3558. size_t i, j;
  3559. j = context->count[0];
  3560. if ((context->count[0] += (uint32_t) len << 3) < j) context->count[1]++;
  3561. context->count[1] += (uint32_t) (len >> 29);
  3562. j = (j >> 3) & 63;
  3563. if ((j + len) > 63) {
  3564. memcpy(&context->buffer[j], data, (i = 64 - j));
  3565. mg_sha1_transform(context->state, context->buffer);
  3566. for (; i + 63 < len; i += 64) {
  3567. mg_sha1_transform(context->state, &data[i]);
  3568. }
  3569. j = 0;
  3570. } else
  3571. i = 0;
  3572. memcpy(&context->buffer[j], &data[i], len - i);
  3573. }
  3574. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *context) {
  3575. unsigned i;
  3576. unsigned char finalcount[8], c;
  3577. for (i = 0; i < 8; i++) {
  3578. finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >>
  3579. ((3 - (i & 3)) * 8)) &
  3580. 255);
  3581. }
  3582. c = 0200;
  3583. mg_sha1_update(context, &c, 1);
  3584. while ((context->count[0] & 504) != 448) {
  3585. c = 0000;
  3586. mg_sha1_update(context, &c, 1);
  3587. }
  3588. mg_sha1_update(context, finalcount, 8);
  3589. for (i = 0; i < 20; i++) {
  3590. digest[i] =
  3591. (unsigned char) ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
  3592. }
  3593. memset(context, '\0', sizeof(*context));
  3594. memset(&finalcount, '\0', sizeof(finalcount));
  3595. }
  3596. #ifdef MG_ENABLE_LINES
  3597. #line 1 "src/sntp.c"
  3598. #endif
  3599. #define SNTP_TIME_OFFSET 2208988800U // (1970 - 1900) in seconds
  3600. #define SNTP_MAX_FRAC 4294967295.0 // 2 ** 32 - 1
  3601. static int64_t gettimestamp(const uint32_t *data) {
  3602. uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
  3603. if (sec) sec -= SNTP_TIME_OFFSET;
  3604. return ((int64_t) sec) * 1000 + (int64_t) (frac / SNTP_MAX_FRAC * 1000.0);
  3605. }
  3606. int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
  3607. int64_t res = -1;
  3608. int mode = len > 0 ? buf[0] & 7 : 0;
  3609. int version = len > 0 ? (buf[0] >> 3) & 7 : 0;
  3610. if (len < 48) {
  3611. MG_ERROR(("%s", "corrupt packet"));
  3612. } else if (mode != 4 && mode != 5) {
  3613. MG_ERROR(("%s", "not a server reply"));
  3614. } else if (buf[1] == 0) {
  3615. MG_ERROR(("%s", "server sent a kiss of death"));
  3616. } else if (version == 4 || version == 3) {
  3617. // int64_t ref = gettimestamp((uint32_t *) &buf[16]);
  3618. int64_t t0 = gettimestamp((uint32_t *) &buf[24]);
  3619. int64_t t1 = gettimestamp((uint32_t *) &buf[32]);
  3620. int64_t t2 = gettimestamp((uint32_t *) &buf[40]);
  3621. int64_t t3 = (int64_t) mg_millis();
  3622. int64_t delta = (t3 - t0) - (t2 - t1);
  3623. MG_VERBOSE(("%lld %lld %lld %lld delta:%lld", t0, t1, t2, t3, delta));
  3624. res = t2 + delta / 2;
  3625. } else {
  3626. MG_ERROR(("unexpected version: %d", version));
  3627. }
  3628. return res;
  3629. }
  3630. static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
  3631. if (ev == MG_EV_READ) {
  3632. int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
  3633. if (milliseconds > 0) {
  3634. MG_INFO(("%lu got time: %lld ms from epoch", c->id, milliseconds));
  3635. mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
  3636. MG_VERBOSE(("%u.%u", (unsigned) (milliseconds / 1000),
  3637. (unsigned) (milliseconds % 1000)));
  3638. }
  3639. mg_iobuf_del(&c->recv, 0, c->recv.len); // Free receive buffer
  3640. } else if (ev == MG_EV_CONNECT) {
  3641. mg_sntp_request(c);
  3642. } else if (ev == MG_EV_CLOSE) {
  3643. }
  3644. (void) fnd;
  3645. (void) evd;
  3646. }
  3647. void mg_sntp_request(struct mg_connection *c) {
  3648. if (c->is_resolving) {
  3649. MG_ERROR(("%lu wait until resolved", c->id));
  3650. } else {
  3651. int64_t now = (int64_t) mg_millis(); // Use int64_t, for vc98
  3652. uint8_t buf[48] = {0};
  3653. uint32_t *t = (uint32_t *) &buf[40];
  3654. double frac = ((double) (now % 1000)) / 1000.0 * SNTP_MAX_FRAC;
  3655. buf[0] = (0 << 6) | (4 << 3) | 3;
  3656. t[0] = mg_htonl((uint32_t) (now / 1000) + SNTP_TIME_OFFSET);
  3657. t[1] = mg_htonl((uint32_t) frac);
  3658. mg_send(c, buf, sizeof(buf));
  3659. }
  3660. }
  3661. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  3662. mg_event_handler_t fn, void *fnd) {
  3663. struct mg_connection *c = NULL;
  3664. if (url == NULL) url = "udp://time.google.com:123";
  3665. if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) c->pfn = sntp_cb;
  3666. return c;
  3667. }
  3668. #ifdef MG_ENABLE_LINES
  3669. #line 1 "src/sock.c"
  3670. #endif
  3671. #if MG_ENABLE_SOCKET
  3672. #ifndef closesocket
  3673. #define closesocket(x) close(x)
  3674. #endif
  3675. #define FD(c_) ((MG_SOCKET_TYPE) (size_t) (c_)->fd)
  3676. #define S2PTR(s_) ((void *) (size_t) (s_))
  3677. #ifndef MSG_NONBLOCKING
  3678. #define MSG_NONBLOCKING 0
  3679. #endif
  3680. #ifndef AF_INET6
  3681. #define AF_INET6 10
  3682. #endif
  3683. #ifndef MG_SOCK_ERR
  3684. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? errno : 0)
  3685. #endif
  3686. #ifndef MG_SOCK_INTR
  3687. #define MG_SOCK_INTR(fd) (fd == MG_INVALID_SOCKET && MG_SOCK_ERR(-1) == EINTR)
  3688. #endif
  3689. #ifndef MG_SOCK_PENDING
  3690. #define MG_SOCK_PENDING(errcode) \
  3691. (((errcode) < 0) && (errno == EINPROGRESS || errno == EWOULDBLOCK))
  3692. #endif
  3693. #ifndef MG_SOCK_RESET
  3694. #define MG_SOCK_RESET(errcode) \
  3695. (((errcode) < 0) && (errno == EPIPE || errno == ECONNRESET))
  3696. #endif
  3697. union usa {
  3698. struct sockaddr sa;
  3699. struct sockaddr_in sin;
  3700. #if MG_ENABLE_IPV6
  3701. struct sockaddr_in6 sin6;
  3702. #endif
  3703. };
  3704. static socklen_t tousa(struct mg_addr *a, union usa *usa) {
  3705. socklen_t len = sizeof(usa->sin);
  3706. memset(usa, 0, sizeof(*usa));
  3707. usa->sin.sin_family = AF_INET;
  3708. usa->sin.sin_port = a->port;
  3709. *(uint32_t *) &usa->sin.sin_addr = a->ip;
  3710. #if MG_ENABLE_IPV6
  3711. if (a->is_ip6) {
  3712. usa->sin.sin_family = AF_INET6;
  3713. usa->sin6.sin6_port = a->port;
  3714. memcpy(&usa->sin6.sin6_addr, a->ip6, sizeof(a->ip6));
  3715. len = sizeof(usa->sin6);
  3716. }
  3717. #endif
  3718. return len;
  3719. }
  3720. static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
  3721. a->is_ip6 = is_ip6;
  3722. a->port = usa->sin.sin_port;
  3723. memcpy(&a->ip, &usa->sin.sin_addr, sizeof(a->ip));
  3724. #if MG_ENABLE_IPV6
  3725. if (is_ip6) {
  3726. memcpy(a->ip6, &usa->sin6.sin6_addr, sizeof(a->ip6));
  3727. a->port = usa->sin6.sin6_port;
  3728. }
  3729. #endif
  3730. }
  3731. static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
  3732. union usa usa;
  3733. socklen_t n = sizeof(usa);
  3734. if (getsockname(fd, &usa.sa, &n) == 0) {
  3735. tomgaddr(&usa, addr, n != sizeof(usa.sin));
  3736. }
  3737. }
  3738. static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
  3739. if (n == MG_IO_WAIT) {
  3740. // Do nothing
  3741. } else if (n <= 0) {
  3742. c->is_closing = 1; // Termination. Don't call mg_error(): #1529
  3743. } else if (n > 0) {
  3744. if (c->is_hexdumping) {
  3745. union usa usa;
  3746. socklen_t slen = sizeof(usa.sin);
  3747. if (getsockname(FD(c), &usa.sa, &slen) < 0) (void) 0; // Ignore result
  3748. MG_INFO(("\n-- %lu %M %s %M %ld", c->id, mg_print_ip_port, &c->loc,
  3749. r ? "<-" : "->", mg_print_ip_port, &c->rem, n));
  3750. mg_hexdump(buf, (size_t) n);
  3751. }
  3752. if (r) {
  3753. c->recv.len += (size_t) n;
  3754. mg_call(c, MG_EV_READ, &n);
  3755. } else {
  3756. mg_iobuf_del(&c->send, 0, (size_t) n);
  3757. // if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
  3758. if (c->send.len == 0) {
  3759. MG_EPOLL_MOD(c, 0);
  3760. }
  3761. mg_call(c, MG_EV_WRITE, &n);
  3762. }
  3763. }
  3764. }
  3765. long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
  3766. long n;
  3767. if (c->is_udp) {
  3768. union usa usa;
  3769. socklen_t slen = tousa(&c->rem, &usa);
  3770. n = sendto(FD(c), (char *) buf, len, 0, &usa.sa, slen);
  3771. if (n > 0) setlocaddr(FD(c), &c->loc);
  3772. } else {
  3773. n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
  3774. }
  3775. if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
  3776. if (MG_SOCK_RESET(n)) return MG_IO_RESET;
  3777. if (n <= 0) return MG_IO_ERR;
  3778. return n;
  3779. }
  3780. bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
  3781. if (c->is_udp) {
  3782. long n = mg_io_send(c, buf, len);
  3783. MG_DEBUG(("%lu %p %d:%d %ld err %d", c->id, c->fd, (int) c->send.len,
  3784. (int) c->recv.len, n, MG_SOCK_ERR(n)));
  3785. iolog(c, (char *) buf, n, false);
  3786. return n > 0;
  3787. } else {
  3788. return mg_iobuf_add(&c->send, c->send.len, buf, len);
  3789. }
  3790. }
  3791. static void mg_set_non_blocking_mode(MG_SOCKET_TYPE fd) {
  3792. #if defined(MG_CUSTOM_NONBLOCK)
  3793. MG_CUSTOM_NONBLOCK(fd);
  3794. #elif MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
  3795. unsigned long on = 1;
  3796. ioctlsocket(fd, FIONBIO, &on);
  3797. #elif MG_ENABLE_RL
  3798. unsigned long on = 1;
  3799. ioctlsocket(fd, FIONBIO, &on);
  3800. #elif MG_ENABLE_FREERTOS_TCP
  3801. const BaseType_t off = 0;
  3802. if (setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off)) != 0) (void) 0;
  3803. if (setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)) != 0) (void) 0;
  3804. #elif MG_ENABLE_LWIP
  3805. lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
  3806. #elif MG_ARCH == MG_ARCH_AZURERTOS
  3807. fcntl(fd, F_SETFL, O_NONBLOCK);
  3808. #elif MG_ARCH == MG_ARCH_TIRTOS
  3809. int val = 0;
  3810. setsockopt(fd, SOL_SOCKET, SO_BLOCKING, &val, sizeof(val));
  3811. // SPRU524J section 3.3.3 page 63, SO_SNDLOWAT
  3812. int sz = sizeof(val);
  3813. getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &sz);
  3814. val /= 2; // set send low-water mark at half send buffer size
  3815. setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val));
  3816. #else
  3817. fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); // Non-blocking mode
  3818. fcntl(fd, F_SETFD, FD_CLOEXEC); // Set close-on-exec
  3819. #endif
  3820. }
  3821. bool mg_open_listener(struct mg_connection *c, const char *url) {
  3822. MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
  3823. bool success = false;
  3824. c->loc.port = mg_htons(mg_url_port(url));
  3825. if (!mg_aton(mg_url_host(url), &c->loc)) {
  3826. MG_ERROR(("invalid listening URL: %s", url));
  3827. } else {
  3828. union usa usa;
  3829. socklen_t slen = tousa(&c->loc, &usa);
  3830. int rc, on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET;
  3831. int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
  3832. int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
  3833. (void) on;
  3834. if ((fd = socket(af, type, proto)) == MG_INVALID_SOCKET) {
  3835. MG_ERROR(("socket: %d", MG_SOCK_ERR(-1)));
  3836. #if defined(SO_REUSEADDR) && (!defined(LWIP_SOCKET) || SO_REUSE)
  3837. } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
  3838. sizeof(on))) != 0) {
  3839. // 1. SO_RESUSEADDR semantics on UNIX and Windows is different. On
  3840. // Windows, SO_REUSEADDR allows to bind a socket to a port without error
  3841. // even if the port is already open by another program. This is not the
  3842. // behavior SO_REUSEADDR was designed for, and leads to hard-to-track
  3843. // failure scenarios.
  3844. //
  3845. // 2. For LWIP, SO_REUSEADDR should be explicitly enabled by defining
  3846. // SO_REUSE = 1 in lwipopts.h, otherwise the code below will compile but
  3847. // won't work! (setsockopt will return EINVAL)
  3848. MG_ERROR(("setsockopt(SO_REUSEADDR): %d", MG_SOCK_ERR(rc)));
  3849. #endif
  3850. #if defined(SO_EXCLUSIVEADDRUSE)
  3851. } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
  3852. (char *) &on, sizeof(on))) != 0) {
  3853. // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
  3854. MG_ERROR(("setsockopt(SO_EXCLUSIVEADDRUSE): %d", MG_SOCK_ERR(rc)));
  3855. #endif
  3856. #if defined(IPV6_V6ONLY)
  3857. } else if (c->loc.is_ip6 &&
  3858. (rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &on,
  3859. sizeof(on))) != 0) {
  3860. // See #2089. Allow to bind v4 and v6 sockets on the same port
  3861. MG_ERROR(("setsockopt(IPV6_V6ONLY): %d", MG_SOCK_ERR(rc)));
  3862. #endif
  3863. } else if ((rc = bind(fd, &usa.sa, slen)) != 0) {
  3864. MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
  3865. } else if ((type == SOCK_STREAM &&
  3866. (rc = listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE)) != 0)) {
  3867. // NOTE(lsm): FreeRTOS uses backlog value as a connection limit
  3868. // In case port was set to 0, get the real port number
  3869. MG_ERROR(("listen: %d", MG_SOCK_ERR(rc)));
  3870. } else {
  3871. setlocaddr(fd, &c->loc);
  3872. mg_set_non_blocking_mode(fd);
  3873. c->fd = S2PTR(fd);
  3874. MG_EPOLL_ADD(c);
  3875. success = true;
  3876. }
  3877. }
  3878. if (success == false && fd != MG_INVALID_SOCKET) closesocket(fd);
  3879. return success;
  3880. }
  3881. long mg_io_recv(struct mg_connection *c, void *buf, size_t len) {
  3882. long n = 0;
  3883. if (c->is_udp) {
  3884. union usa usa;
  3885. socklen_t slen = tousa(&c->rem, &usa);
  3886. n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
  3887. if (n > 0) tomgaddr(&usa, &c->rem, slen != sizeof(usa.sin));
  3888. } else {
  3889. n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
  3890. }
  3891. if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
  3892. if (MG_SOCK_RESET(n)) return MG_IO_RESET;
  3893. if (n <= 0) return MG_IO_ERR;
  3894. return n;
  3895. }
  3896. // NOTE(lsm): do only one iteration of reads, cause some systems
  3897. // (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
  3898. static void read_conn(struct mg_connection *c) {
  3899. long n = -1;
  3900. if (c->recv.len >= MG_MAX_RECV_SIZE) {
  3901. mg_error(c, "max_recv_buf_size reached");
  3902. } else if (c->recv.size <= c->recv.len &&
  3903. !mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE)) {
  3904. mg_error(c, "oom");
  3905. } else {
  3906. char *buf = (char *) &c->recv.buf[c->recv.len];
  3907. size_t len = c->recv.size - c->recv.len;
  3908. n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_io_recv(c, buf, len);
  3909. MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
  3910. (long) c->send.len, (long) c->send.size, (long) c->recv.len,
  3911. (long) c->recv.size, n, MG_SOCK_ERR(n)));
  3912. iolog(c, buf, n, true);
  3913. }
  3914. }
  3915. static void write_conn(struct mg_connection *c) {
  3916. char *buf = (char *) c->send.buf;
  3917. size_t len = c->send.len;
  3918. long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_io_send(c, buf, len);
  3919. MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
  3920. (long) c->send.len, (long) c->send.size, (long) c->recv.len,
  3921. (long) c->recv.size, n, MG_SOCK_ERR(n)));
  3922. iolog(c, buf, n, false);
  3923. }
  3924. static void close_conn(struct mg_connection *c) {
  3925. if (FD(c) != MG_INVALID_SOCKET) {
  3926. #if MG_ENABLE_EPOLL
  3927. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_DEL, FD(c), NULL);
  3928. #endif
  3929. closesocket(FD(c));
  3930. #if MG_ENABLE_FREERTOS_TCP
  3931. FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL);
  3932. #endif
  3933. }
  3934. mg_close_conn(c);
  3935. }
  3936. static void connect_conn(struct mg_connection *c) {
  3937. union usa usa;
  3938. socklen_t n = sizeof(usa);
  3939. // Use getpeername() to test whether we have connected
  3940. if (getpeername(FD(c), &usa.sa, &n) == 0) {
  3941. c->is_connecting = 0;
  3942. mg_call(c, MG_EV_CONNECT, NULL);
  3943. MG_EPOLL_MOD(c, 0);
  3944. if (c->is_tls_hs) mg_tls_handshake(c);
  3945. } else {
  3946. mg_error(c, "socket error");
  3947. }
  3948. }
  3949. static void setsockopts(struct mg_connection *c) {
  3950. #if MG_ENABLE_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS || \
  3951. MG_ARCH == MG_ARCH_TIRTOS
  3952. (void) c;
  3953. #else
  3954. int on = 1;
  3955. #if !defined(SOL_TCP)
  3956. #define SOL_TCP IPPROTO_TCP
  3957. #endif
  3958. if (setsockopt(FD(c), SOL_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) != 0)
  3959. (void) 0;
  3960. if (setsockopt(FD(c), SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) !=
  3961. 0)
  3962. (void) 0;
  3963. #endif
  3964. }
  3965. void mg_connect_resolved(struct mg_connection *c) {
  3966. int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
  3967. int rc, af = c->rem.is_ip6 ? AF_INET6 : AF_INET; // c->rem has resolved IP
  3968. c->fd = S2PTR(socket(af, type, 0)); // Create outbound socket
  3969. c->is_resolving = 0; // Clear resolving flag
  3970. if (FD(c) == MG_INVALID_SOCKET) {
  3971. mg_error(c, "socket(): %d", MG_SOCK_ERR(-1));
  3972. } else if (c->is_udp) {
  3973. MG_EPOLL_ADD(c);
  3974. #if MG_ARCH == MG_ARCH_TIRTOS
  3975. union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets
  3976. socklen_t slen = tousa(&c->loc, &usa);
  3977. if ((rc = bind(c->fd, &usa.sa, slen)) != 0)
  3978. MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
  3979. #endif
  3980. mg_call(c, MG_EV_RESOLVE, NULL);
  3981. mg_call(c, MG_EV_CONNECT, NULL);
  3982. } else {
  3983. union usa usa;
  3984. socklen_t slen = tousa(&c->rem, &usa);
  3985. mg_set_non_blocking_mode(FD(c));
  3986. setsockopts(c);
  3987. MG_EPOLL_ADD(c);
  3988. mg_call(c, MG_EV_RESOLVE, NULL);
  3989. rc = connect(FD(c), &usa.sa, slen); // Attempt to connect
  3990. if (rc == 0) { // Success
  3991. mg_call(c, MG_EV_CONNECT, NULL); // Send MG_EV_CONNECT to the user
  3992. } else if (MG_SOCK_PENDING(rc)) { // Need to wait for TCP handshake
  3993. MG_DEBUG(("%lu %p -> %M pend", c->id, c->fd, mg_print_ip_port, &c->rem));
  3994. c->is_connecting = 1;
  3995. } else {
  3996. mg_error(c, "connect: %d", MG_SOCK_ERR(rc));
  3997. }
  3998. }
  3999. }
  4000. static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa,
  4001. socklen_t *len) {
  4002. MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
  4003. do {
  4004. memset(usa, 0, sizeof(*usa));
  4005. fd = accept(sock, &usa->sa, len);
  4006. } while (MG_SOCK_INTR(fd));
  4007. return fd;
  4008. }
  4009. static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
  4010. struct mg_connection *c = NULL;
  4011. union usa usa;
  4012. socklen_t sa_len = sizeof(usa);
  4013. MG_SOCKET_TYPE fd = raccept(FD(lsn), &usa, &sa_len);
  4014. if (fd == MG_INVALID_SOCKET) {
  4015. #if MG_ARCH == MG_ARCH_AZURERTOS
  4016. // AzureRTOS, in non-block socket mode can mark listening socket readable
  4017. // even it is not. See comment for 'select' func implementation in
  4018. // nx_bsd.c That's not an error, just should try later
  4019. if (errno != EAGAIN)
  4020. #endif
  4021. MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERR(-1)));
  4022. #if (MG_ARCH != MG_ARCH_WIN32) && !MG_ENABLE_FREERTOS_TCP && \
  4023. (MG_ARCH != MG_ARCH_TIRTOS) && !MG_ENABLE_POLL
  4024. } else if ((long) fd >= FD_SETSIZE) {
  4025. MG_ERROR(("%ld > %ld", (long) fd, (long) FD_SETSIZE));
  4026. closesocket(fd);
  4027. #endif
  4028. } else if ((c = mg_alloc_conn(mgr)) == NULL) {
  4029. MG_ERROR(("%lu OOM", lsn->id));
  4030. closesocket(fd);
  4031. } else {
  4032. tomgaddr(&usa, &c->rem, sa_len != sizeof(usa.sin));
  4033. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  4034. c->fd = S2PTR(fd);
  4035. MG_EPOLL_ADD(c);
  4036. mg_set_non_blocking_mode(FD(c));
  4037. setsockopts(c);
  4038. c->is_accepted = 1;
  4039. c->is_hexdumping = lsn->is_hexdumping;
  4040. c->loc = lsn->loc;
  4041. c->pfn = lsn->pfn;
  4042. c->pfn_data = lsn->pfn_data;
  4043. c->fn = lsn->fn;
  4044. c->fn_data = lsn->fn_data;
  4045. MG_DEBUG(("%lu %p accepted %M -> %M", c->id, c->fd, mg_print_ip_port,
  4046. &c->rem, mg_print_ip_port, &c->loc));
  4047. mg_call(c, MG_EV_OPEN, NULL);
  4048. mg_call(c, MG_EV_ACCEPT, NULL);
  4049. }
  4050. }
  4051. static bool mg_socketpair(MG_SOCKET_TYPE sp[2], union usa usa[2], bool udp) {
  4052. MG_SOCKET_TYPE sock;
  4053. socklen_t n = sizeof(usa[0].sin);
  4054. bool success = false;
  4055. sock = sp[0] = sp[1] = MG_INVALID_SOCKET;
  4056. (void) memset(&usa[0], 0, sizeof(usa[0]));
  4057. usa[0].sin.sin_family = AF_INET;
  4058. *(uint32_t *) &usa->sin.sin_addr = mg_htonl(0x7f000001U); // 127.0.0.1
  4059. usa[1] = usa[0];
  4060. if (udp && (sp[0] = socket(AF_INET, SOCK_DGRAM, 0)) != MG_INVALID_SOCKET &&
  4061. (sp[1] = socket(AF_INET, SOCK_DGRAM, 0)) != MG_INVALID_SOCKET &&
  4062. bind(sp[0], &usa[0].sa, n) == 0 && bind(sp[1], &usa[1].sa, n) == 0 &&
  4063. getsockname(sp[0], &usa[0].sa, &n) == 0 &&
  4064. getsockname(sp[1], &usa[1].sa, &n) == 0 &&
  4065. connect(sp[0], &usa[1].sa, n) == 0 &&
  4066. connect(sp[1], &usa[0].sa, n) == 0) {
  4067. success = true;
  4068. } else if (!udp &&
  4069. (sock = socket(AF_INET, SOCK_STREAM, 0)) != MG_INVALID_SOCKET &&
  4070. bind(sock, &usa[0].sa, n) == 0 &&
  4071. listen(sock, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0 &&
  4072. getsockname(sock, &usa[0].sa, &n) == 0 &&
  4073. (sp[0] = socket(AF_INET, SOCK_STREAM, 0)) != MG_INVALID_SOCKET &&
  4074. connect(sp[0], &usa[0].sa, n) == 0 &&
  4075. (sp[1] = raccept(sock, &usa[1], &n)) != MG_INVALID_SOCKET) {
  4076. success = true;
  4077. }
  4078. if (success) {
  4079. mg_set_non_blocking_mode(sp[1]);
  4080. } else {
  4081. if (sp[0] != MG_INVALID_SOCKET) closesocket(sp[0]);
  4082. if (sp[1] != MG_INVALID_SOCKET) closesocket(sp[1]);
  4083. sp[0] = sp[1] = MG_INVALID_SOCKET;
  4084. }
  4085. if (sock != MG_INVALID_SOCKET) closesocket(sock);
  4086. return success;
  4087. }
  4088. int mg_mkpipe(struct mg_mgr *mgr, mg_event_handler_t fn, void *fn_data,
  4089. bool udp) {
  4090. union usa usa[2];
  4091. MG_SOCKET_TYPE sp[2] = {MG_INVALID_SOCKET, MG_INVALID_SOCKET};
  4092. struct mg_connection *c = NULL;
  4093. if (!mg_socketpair(sp, usa, udp)) {
  4094. MG_ERROR(("Cannot create socket pair"));
  4095. } else if ((c = mg_wrapfd(mgr, (int) sp[1], fn, fn_data)) == NULL) {
  4096. closesocket(sp[0]);
  4097. closesocket(sp[1]);
  4098. sp[0] = sp[1] = MG_INVALID_SOCKET;
  4099. } else {
  4100. tomgaddr(&usa[0], &c->rem, false);
  4101. MG_DEBUG(("%lu %p pipe %lu", c->id, c->fd, (unsigned long) sp[0]));
  4102. }
  4103. return (int) sp[0];
  4104. }
  4105. static bool can_read(const struct mg_connection *c) {
  4106. return c->is_full == false;
  4107. }
  4108. static bool can_write(const struct mg_connection *c) {
  4109. return c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0);
  4110. }
  4111. static bool skip_iotest(const struct mg_connection *c) {
  4112. return (c->is_closing || c->is_resolving || FD(c) == MG_INVALID_SOCKET) ||
  4113. (can_read(c) == false && can_write(c) == false);
  4114. }
  4115. static void mg_iotest(struct mg_mgr *mgr, int ms) {
  4116. #if MG_ENABLE_FREERTOS_TCP
  4117. struct mg_connection *c;
  4118. for (c = mgr->conns; c != NULL; c = c->next) {
  4119. c->is_readable = c->is_writable = 0;
  4120. if (skip_iotest(c)) continue;
  4121. if (can_read(c))
  4122. FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT);
  4123. if (can_write(c)) FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_WRITE);
  4124. }
  4125. FreeRTOS_select(mgr->ss, pdMS_TO_TICKS(ms));
  4126. for (c = mgr->conns; c != NULL; c = c->next) {
  4127. EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss);
  4128. c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1U : 0;
  4129. c->is_writable = bits & eSELECT_WRITE ? 1U : 0;
  4130. if (c->fd != MG_INVALID_SOCKET)
  4131. FreeRTOS_FD_CLR(c->fd, mgr->ss,
  4132. eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE);
  4133. }
  4134. #elif MG_ENABLE_EPOLL
  4135. size_t max = 1;
  4136. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  4137. c->is_readable = c->is_writable = 0;
  4138. if (mg_tls_pending(c) > 0) ms = 1, c->is_readable = 1;
  4139. if (can_write(c)) MG_EPOLL_MOD(c, 1);
  4140. max++;
  4141. }
  4142. struct epoll_event *evs = (struct epoll_event *) alloca(max * sizeof(evs[0]));
  4143. int n = epoll_wait(mgr->epoll_fd, evs, (int) max, ms);
  4144. for (int i = 0; i < n; i++) {
  4145. struct mg_connection *c = (struct mg_connection *) evs[i].data.ptr;
  4146. if (evs[i].events & EPOLLERR) {
  4147. mg_error(c, "socket error");
  4148. } else if (c->is_readable == 0) {
  4149. bool rd = evs[i].events & (EPOLLIN | EPOLLHUP);
  4150. bool wr = evs[i].events & EPOLLOUT;
  4151. c->is_readable = can_read(c) && rd ? 1U : 0;
  4152. c->is_writable = can_write(c) && wr ? 1U : 0;
  4153. }
  4154. }
  4155. (void) skip_iotest;
  4156. #elif MG_ENABLE_POLL
  4157. nfds_t n = 0;
  4158. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) n++;
  4159. struct pollfd *fds = (struct pollfd *) alloca(n * sizeof(fds[0]));
  4160. memset(fds, 0, n * sizeof(fds[0]));
  4161. n = 0;
  4162. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  4163. c->is_readable = c->is_writable = 0;
  4164. if (skip_iotest(c)) {
  4165. // Socket not valid, ignore
  4166. } else if (mg_tls_pending(c) > 0) {
  4167. ms = 1; // Don't wait if TLS is ready
  4168. } else {
  4169. fds[n].fd = FD(c);
  4170. if (can_read(c)) fds[n].events |= POLLIN;
  4171. if (can_write(c)) fds[n].events |= POLLOUT;
  4172. n++;
  4173. }
  4174. }
  4175. // MG_INFO(("poll n=%d ms=%d", (int) n, ms));
  4176. if (poll(fds, n, ms) < 0) {
  4177. #if MG_ARCH == MG_ARCH_WIN32
  4178. if (n == 0) Sleep(ms); // On Windows, poll fails if no sockets
  4179. #endif
  4180. memset(fds, 0, n * sizeof(fds[0]));
  4181. }
  4182. n = 0;
  4183. for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
  4184. if (skip_iotest(c)) {
  4185. // Socket not valid, ignore
  4186. } else if (mg_tls_pending(c) > 0) {
  4187. c->is_readable = 1;
  4188. } else {
  4189. if (fds[n].revents & POLLERR) {
  4190. mg_error(c, "socket error");
  4191. } else {
  4192. c->is_readable =
  4193. (unsigned) (fds[n].revents & (POLLIN | POLLHUP) ? 1 : 0);
  4194. c->is_writable = (unsigned) (fds[n].revents & POLLOUT ? 1 : 0);
  4195. }
  4196. n++;
  4197. }
  4198. }
  4199. #else
  4200. struct timeval tv = {ms / 1000, (ms % 1000) * 1000}, tv_zero = {0, 0}, *tvp;
  4201. struct mg_connection *c;
  4202. fd_set rset, wset, eset;
  4203. MG_SOCKET_TYPE maxfd = 0;
  4204. int rc;
  4205. FD_ZERO(&rset);
  4206. FD_ZERO(&wset);
  4207. FD_ZERO(&eset);
  4208. tvp = ms < 0 ? NULL : &tv;
  4209. for (c = mgr->conns; c != NULL; c = c->next) {
  4210. c->is_readable = c->is_writable = 0;
  4211. if (skip_iotest(c)) continue;
  4212. FD_SET(FD(c), &eset);
  4213. if (can_read(c)) FD_SET(FD(c), &rset);
  4214. if (can_write(c)) FD_SET(FD(c), &wset);
  4215. if (mg_tls_pending(c) > 0) tvp = &tv_zero;
  4216. if (FD(c) > maxfd) maxfd = FD(c);
  4217. }
  4218. if ((rc = select((int) maxfd + 1, &rset, &wset, &eset, tvp)) < 0) {
  4219. #if MG_ARCH == MG_ARCH_WIN32
  4220. if (maxfd == 0) Sleep(ms); // On Windows, select fails if no sockets
  4221. #else
  4222. MG_ERROR(("select: %d %d", rc, MG_SOCK_ERR(rc)));
  4223. #endif
  4224. FD_ZERO(&rset);
  4225. FD_ZERO(&wset);
  4226. FD_ZERO(&eset);
  4227. }
  4228. for (c = mgr->conns; c != NULL; c = c->next) {
  4229. if (FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &eset)) {
  4230. mg_error(c, "socket error");
  4231. } else {
  4232. c->is_readable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &rset);
  4233. c->is_writable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &wset);
  4234. if (mg_tls_pending(c) > 0) c->is_readable = 1;
  4235. }
  4236. }
  4237. #endif
  4238. }
  4239. void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
  4240. struct mg_connection *c, *tmp;
  4241. uint64_t now;
  4242. mg_iotest(mgr, ms);
  4243. now = mg_millis();
  4244. mg_timer_poll(&mgr->timers, now);
  4245. for (c = mgr->conns; c != NULL; c = tmp) {
  4246. bool is_resp = c->is_resp;
  4247. tmp = c->next;
  4248. mg_call(c, MG_EV_POLL, &now);
  4249. if (is_resp && !c->is_resp) {
  4250. long n = 0;
  4251. mg_call(c, MG_EV_READ, &n);
  4252. }
  4253. MG_VERBOSE(("%lu %c%c %c%c%c%c%c", c->id, c->is_readable ? 'r' : '-',
  4254. c->is_writable ? 'w' : '-', c->is_tls ? 'T' : 't',
  4255. c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
  4256. c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
  4257. if (c->is_resolving || c->is_closing) {
  4258. // Do nothing
  4259. } else if (c->is_listening && c->is_udp == 0) {
  4260. if (c->is_readable) accept_conn(mgr, c);
  4261. } else if (c->is_connecting) {
  4262. if (c->is_readable || c->is_writable) connect_conn(c);
  4263. } else if (c->is_tls_hs) {
  4264. if ((c->is_readable || c->is_writable)) mg_tls_handshake(c);
  4265. } else {
  4266. if (c->is_readable) read_conn(c);
  4267. if (c->is_writable) write_conn(c);
  4268. }
  4269. if (c->is_draining && c->send.len == 0) c->is_closing = 1;
  4270. if (c->is_closing) close_conn(c);
  4271. }
  4272. }
  4273. #endif
  4274. #ifdef MG_ENABLE_LINES
  4275. #line 1 "src/ssi.c"
  4276. #endif
  4277. #ifndef MG_MAX_SSI_DEPTH
  4278. #define MG_MAX_SSI_DEPTH 5
  4279. #endif
  4280. #ifndef MG_SSI_BUFSIZ
  4281. #define MG_SSI_BUFSIZ 1024
  4282. #endif
  4283. #if MG_ENABLE_SSI
  4284. static char *mg_ssi(const char *path, const char *root, int depth) {
  4285. struct mg_iobuf b = {NULL, 0, 0, MG_IO_SIZE};
  4286. FILE *fp = fopen(path, "rb");
  4287. if (fp != NULL) {
  4288. char buf[MG_SSI_BUFSIZ], arg[sizeof(buf)];
  4289. int ch, intag = 0;
  4290. size_t len = 0;
  4291. buf[0] = arg[0] = '\0';
  4292. while ((ch = fgetc(fp)) != EOF) {
  4293. if (intag && ch == '>' && buf[len - 1] == '-' && buf[len - 2] == '-') {
  4294. buf[len++] = (char) (ch & 0xff);
  4295. buf[len] = '\0';
  4296. if (sscanf(buf, "<!--#include file=\"%[^\"]", arg)) {
  4297. char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10],
  4298. *p = (char *) path + strlen(path), *data;
  4299. while (p > path && p[-1] != MG_DIRSEP && p[-1] != '/') p--;
  4300. mg_snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
  4301. if (depth < MG_MAX_SSI_DEPTH &&
  4302. (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
  4303. mg_iobuf_add(&b, b.len, data, strlen(data));
  4304. free(data);
  4305. } else {
  4306. MG_ERROR(("%s: file=%s error or too deep", path, arg));
  4307. }
  4308. } else if (sscanf(buf, "<!--#include virtual=\"%[^\"]", arg)) {
  4309. char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10], *data;
  4310. mg_snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
  4311. if (depth < MG_MAX_SSI_DEPTH &&
  4312. (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
  4313. mg_iobuf_add(&b, b.len, data, strlen(data));
  4314. free(data);
  4315. } else {
  4316. MG_ERROR(("%s: virtual=%s error or too deep", path, arg));
  4317. }
  4318. } else {
  4319. // Unknown SSI tag
  4320. MG_ERROR(("Unknown SSI tag: %.*s", (int) len, buf));
  4321. mg_iobuf_add(&b, b.len, buf, len);
  4322. }
  4323. intag = 0;
  4324. len = 0;
  4325. } else if (ch == '<') {
  4326. intag = 1;
  4327. if (len > 0) mg_iobuf_add(&b, b.len, buf, len);
  4328. len = 0;
  4329. buf[len++] = (char) (ch & 0xff);
  4330. } else if (intag) {
  4331. if (len == 5 && strncmp(buf, "<!--#", 5) != 0) {
  4332. intag = 0;
  4333. } else if (len >= sizeof(buf) - 2) {
  4334. MG_ERROR(("%s: SSI tag is too large", path));
  4335. len = 0;
  4336. }
  4337. buf[len++] = (char) (ch & 0xff);
  4338. } else {
  4339. buf[len++] = (char) (ch & 0xff);
  4340. if (len >= sizeof(buf)) {
  4341. mg_iobuf_add(&b, b.len, buf, len);
  4342. len = 0;
  4343. }
  4344. }
  4345. }
  4346. if (len > 0) mg_iobuf_add(&b, b.len, buf, len);
  4347. if (b.len > 0) mg_iobuf_add(&b, b.len, "", 1); // nul-terminate
  4348. fclose(fp);
  4349. }
  4350. (void) depth;
  4351. (void) root;
  4352. return (char *) b.buf;
  4353. }
  4354. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  4355. const char *fullpath) {
  4356. const char *headers = "Content-Type: text/html; charset=utf-8\r\n";
  4357. char *data = mg_ssi(fullpath, root, 0);
  4358. mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data);
  4359. free(data);
  4360. }
  4361. #else
  4362. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  4363. const char *fullpath) {
  4364. mg_http_reply(c, 501, NULL, "SSI not enabled");
  4365. (void) root, (void) fullpath;
  4366. }
  4367. #endif
  4368. #ifdef MG_ENABLE_LINES
  4369. #line 1 "src/str.c"
  4370. #endif
  4371. struct mg_str mg_str_s(const char *s) {
  4372. struct mg_str str = {s, s == NULL ? 0 : strlen(s)};
  4373. return str;
  4374. }
  4375. struct mg_str mg_str_n(const char *s, size_t n) {
  4376. struct mg_str str = {s, n};
  4377. return str;
  4378. }
  4379. int mg_lower(const char *s) {
  4380. int c = *s;
  4381. if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
  4382. return c;
  4383. }
  4384. int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
  4385. int diff = 0;
  4386. if (len > 0) do {
  4387. diff = mg_lower(s1++) - mg_lower(s2++);
  4388. } while (diff == 0 && s1[-1] != '\0' && --len > 0);
  4389. return diff;
  4390. }
  4391. int mg_casecmp(const char *s1, const char *s2) {
  4392. return mg_ncasecmp(s1, s2, (size_t) ~0);
  4393. }
  4394. int mg_vcmp(const struct mg_str *s1, const char *s2) {
  4395. size_t n2 = strlen(s2), n1 = s1->len;
  4396. int r = strncmp(s1->ptr, s2, (n1 < n2) ? n1 : n2);
  4397. if (r == 0) return (int) (n1 - n2);
  4398. return r;
  4399. }
  4400. int mg_vcasecmp(const struct mg_str *str1, const char *str2) {
  4401. size_t n2 = strlen(str2), n1 = str1->len;
  4402. int r = mg_ncasecmp(str1->ptr, str2, (n1 < n2) ? n1 : n2);
  4403. if (r == 0) return (int) (n1 - n2);
  4404. return r;
  4405. }
  4406. struct mg_str mg_strdup(const struct mg_str s) {
  4407. struct mg_str r = {NULL, 0};
  4408. if (s.len > 0 && s.ptr != NULL) {
  4409. char *sc = (char *) calloc(1, s.len + 1);
  4410. if (sc != NULL) {
  4411. memcpy(sc, s.ptr, s.len);
  4412. sc[s.len] = '\0';
  4413. r.ptr = sc;
  4414. r.len = s.len;
  4415. }
  4416. }
  4417. return r;
  4418. }
  4419. int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
  4420. size_t i = 0;
  4421. while (i < str1.len && i < str2.len) {
  4422. int c1 = str1.ptr[i];
  4423. int c2 = str2.ptr[i];
  4424. if (c1 < c2) return -1;
  4425. if (c1 > c2) return 1;
  4426. i++;
  4427. }
  4428. if (i < str1.len) return 1;
  4429. if (i < str2.len) return -1;
  4430. return 0;
  4431. }
  4432. const char *mg_strstr(const struct mg_str haystack,
  4433. const struct mg_str needle) {
  4434. size_t i;
  4435. if (needle.len > haystack.len) return NULL;
  4436. if (needle.len == 0) return haystack.ptr;
  4437. for (i = 0; i <= haystack.len - needle.len; i++) {
  4438. if (memcmp(haystack.ptr + i, needle.ptr, needle.len) == 0) {
  4439. return haystack.ptr + i;
  4440. }
  4441. }
  4442. return NULL;
  4443. }
  4444. static bool is_space(int c) {
  4445. return c == ' ' || c == '\r' || c == '\n' || c == '\t';
  4446. }
  4447. struct mg_str mg_strstrip(struct mg_str s) {
  4448. while (s.len > 0 && is_space((int) *s.ptr)) s.ptr++, s.len--;
  4449. while (s.len > 0 && is_space((int) *(s.ptr + s.len - 1))) s.len--;
  4450. return s;
  4451. }
  4452. bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
  4453. size_t i = 0, j = 0, ni = 0, nj = 0;
  4454. if (caps) caps->ptr = NULL, caps->len = 0;
  4455. while (i < p.len || j < s.len) {
  4456. if (i < p.len && j < s.len && (p.ptr[i] == '?' || s.ptr[j] == p.ptr[i])) {
  4457. if (caps == NULL) {
  4458. } else if (p.ptr[i] == '?') {
  4459. caps->ptr = &s.ptr[j], caps->len = 1; // Finalize `?` cap
  4460. caps++, caps->ptr = NULL, caps->len = 0; // Init next cap
  4461. } else if (caps->ptr != NULL && caps->len == 0) {
  4462. caps->len = (size_t) (&s.ptr[j] - caps->ptr); // Finalize current cap
  4463. caps++, caps->len = 0, caps->ptr = NULL; // Init next cap
  4464. }
  4465. i++, j++;
  4466. } else if (i < p.len && (p.ptr[i] == '*' || p.ptr[i] == '#')) {
  4467. if (caps && !caps->ptr) caps->len = 0, caps->ptr = &s.ptr[j]; // Init cap
  4468. ni = i++, nj = j + 1;
  4469. } else if (nj > 0 && nj <= s.len && (p.ptr[ni] == '#' || s.ptr[j] != '/')) {
  4470. i = ni, j = nj;
  4471. if (caps && caps->ptr == NULL && caps->len == 0) {
  4472. caps--, caps->len = 0; // Restart previous cap
  4473. }
  4474. } else {
  4475. return false;
  4476. }
  4477. }
  4478. if (caps && caps->ptr && caps->len == 0) {
  4479. caps->len = (size_t) (&s.ptr[j] - caps->ptr);
  4480. }
  4481. return true;
  4482. }
  4483. bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
  4484. return mg_match(mg_str_n(s2, n2), mg_str_n(s1, n1), NULL);
  4485. }
  4486. static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
  4487. size_t *klen, size_t *voff, size_t *vlen, char delim) {
  4488. size_t kvlen, kl;
  4489. for (kvlen = 0; ofs + kvlen < n && s[ofs + kvlen] != delim;) kvlen++;
  4490. for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
  4491. if (koff != NULL) *koff = ofs;
  4492. if (klen != NULL) *klen = kl;
  4493. if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
  4494. if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
  4495. ofs += kvlen + 1;
  4496. return ofs > n ? n : ofs;
  4497. }
  4498. bool mg_split(struct mg_str *s, struct mg_str *k, struct mg_str *v, char sep) {
  4499. size_t koff = 0, klen = 0, voff = 0, vlen = 0, off = 0;
  4500. if (s->ptr == NULL || s->len == 0) return 0;
  4501. off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen, sep);
  4502. if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
  4503. if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
  4504. *s = mg_str_n(s->ptr + off, s->len - off);
  4505. return off > 0;
  4506. }
  4507. bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
  4508. return mg_split(s, k, v, ',');
  4509. }
  4510. char *mg_hex(const void *buf, size_t len, char *to) {
  4511. const unsigned char *p = (const unsigned char *) buf;
  4512. const char *hex = "0123456789abcdef";
  4513. size_t i = 0;
  4514. for (; len--; p++) {
  4515. to[i++] = hex[p[0] >> 4];
  4516. to[i++] = hex[p[0] & 0x0f];
  4517. }
  4518. to[i] = '\0';
  4519. return to;
  4520. }
  4521. static unsigned char mg_unhex_nimble(unsigned char c) {
  4522. return (c >= '0' && c <= '9') ? (unsigned char) (c - '0')
  4523. : (c >= 'A' && c <= 'F') ? (unsigned char) (c - '7')
  4524. : (unsigned char) (c - 'W');
  4525. }
  4526. unsigned long mg_unhexn(const char *s, size_t len) {
  4527. unsigned long i = 0, v = 0;
  4528. for (i = 0; i < len; i++) v <<= 4, v |= mg_unhex_nimble(((uint8_t *) s)[i]);
  4529. return v;
  4530. }
  4531. void mg_unhex(const char *buf, size_t len, unsigned char *to) {
  4532. size_t i;
  4533. for (i = 0; i < len; i += 2) {
  4534. to[i >> 1] = (unsigned char) mg_unhexn(&buf[i], 2);
  4535. }
  4536. }
  4537. uint64_t mg_tou64(struct mg_str str) {
  4538. uint64_t result = 0;
  4539. size_t i = 0;
  4540. while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
  4541. while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
  4542. result *= 10;
  4543. result += (unsigned) (str.ptr[i] - '0');
  4544. i++;
  4545. }
  4546. return result;
  4547. }
  4548. int64_t mg_to64(struct mg_str str) {
  4549. int64_t result = 0, neg = 1, max = 922337203685477570 /* INT64_MAX/10-10 */;
  4550. size_t i = 0;
  4551. while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
  4552. if (i < str.len && str.ptr[i] == '-') neg = -1, i++;
  4553. while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
  4554. if (result > max) return 0;
  4555. result *= 10;
  4556. result += (str.ptr[i] - '0');
  4557. i++;
  4558. }
  4559. return result * neg;
  4560. }
  4561. char *mg_remove_double_dots(char *s) {
  4562. char *saved = s, *p = s;
  4563. while (*s != '\0') {
  4564. *p++ = *s++;
  4565. if (s[-1] == '/' || s[-1] == '\\') {
  4566. while (s[0] != '\0') {
  4567. if (s[0] == '/' || s[0] == '\\') {
  4568. s++;
  4569. } else if (s[0] == '.' && s[1] == '.' &&
  4570. (s[2] == '/' || s[2] == '\\')) {
  4571. s += 2;
  4572. } else {
  4573. break;
  4574. }
  4575. }
  4576. }
  4577. }
  4578. *p = '\0';
  4579. return saved;
  4580. }
  4581. #ifdef MG_ENABLE_LINES
  4582. #line 1 "src/timer.c"
  4583. #endif
  4584. #define MG_TIMER_CALLED 4
  4585. void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
  4586. unsigned flags, void (*fn)(void *), void *arg) {
  4587. t->id = 0, t->period_ms = ms, t->expire = 0;
  4588. t->flags = flags, t->fn = fn, t->arg = arg, t->next = *head;
  4589. *head = t;
  4590. }
  4591. void mg_timer_free(struct mg_timer **head, struct mg_timer *t) {
  4592. while (*head && *head != t) head = &(*head)->next;
  4593. if (*head) *head = t->next;
  4594. }
  4595. // t: expiration time, prd: period, now: current time. Return true if expired
  4596. bool mg_timer_expired(uint64_t *t, uint64_t prd, uint64_t now) {
  4597. if (now + prd < *t) *t = 0; // Time wrapped? Reset timer
  4598. if (*t == 0) *t = now + prd; // Firt poll? Set expiration
  4599. if (*t > now) return false; // Not expired yet, return
  4600. *t = (now - *t) > prd ? now + prd : *t + prd; // Next expiration time
  4601. return true; // Expired, return true
  4602. }
  4603. void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
  4604. struct mg_timer *t, *tmp;
  4605. for (t = *head; t != NULL; t = tmp) {
  4606. bool once = t->expire == 0 && (t->flags & MG_TIMER_RUN_NOW) &&
  4607. !(t->flags & MG_TIMER_CALLED); // Handle MG_TIMER_NOW only once
  4608. bool expired = mg_timer_expired(&t->expire, t->period_ms, now_ms);
  4609. tmp = t->next;
  4610. if (!once && !expired) continue;
  4611. if ((t->flags & MG_TIMER_REPEAT) || !(t->flags & MG_TIMER_CALLED)) {
  4612. t->fn(t->arg);
  4613. }
  4614. t->flags |= MG_TIMER_CALLED;
  4615. }
  4616. }
  4617. #ifdef MG_ENABLE_LINES
  4618. #line 1 "src/tls_dummy.c"
  4619. #endif
  4620. #if !MG_ENABLE_MBEDTLS && !MG_ENABLE_OPENSSL && !MG_ENABLE_CUSTOM_TLS
  4621. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  4622. (void) opts;
  4623. mg_error(c, "TLS is not enabled");
  4624. }
  4625. void mg_tls_handshake(struct mg_connection *c) {
  4626. (void) c;
  4627. }
  4628. void mg_tls_free(struct mg_connection *c) {
  4629. (void) c;
  4630. }
  4631. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  4632. return c == NULL || buf == NULL || len == 0 ? 0 : -1;
  4633. }
  4634. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  4635. return c == NULL || buf == NULL || len == 0 ? 0 : -1;
  4636. }
  4637. size_t mg_tls_pending(struct mg_connection *c) {
  4638. (void) c;
  4639. return 0;
  4640. }
  4641. #endif
  4642. #ifdef MG_ENABLE_LINES
  4643. #line 1 "src/tls_mbed.c"
  4644. #endif
  4645. #if MG_ENABLE_MBEDTLS
  4646. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
  4647. #define MGRNG , rng_get, NULL
  4648. #else
  4649. #define MGRNG
  4650. #endif
  4651. void mg_tls_free(struct mg_connection *c) {
  4652. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4653. if (tls != NULL) {
  4654. free(tls->cafile);
  4655. mbedtls_ssl_free(&tls->ssl);
  4656. mbedtls_pk_free(&tls->pk);
  4657. mbedtls_x509_crt_free(&tls->ca);
  4658. mbedtls_x509_crt_free(&tls->cert);
  4659. mbedtls_ssl_config_free(&tls->conf);
  4660. free(tls);
  4661. c->tls = NULL;
  4662. }
  4663. }
  4664. static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
  4665. long n = mg_io_send((struct mg_connection *) ctx, buf, len);
  4666. MG_VERBOSE(("%lu n=%ld e=%d", ((struct mg_connection *) ctx)->id, n, errno));
  4667. if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
  4668. if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
  4669. if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_SEND_FAILED;
  4670. return (int) n;
  4671. }
  4672. static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) {
  4673. long n = mg_io_recv((struct mg_connection *) ctx, buf, len);
  4674. MG_VERBOSE(("%lu n=%ld", ((struct mg_connection *) ctx)->id, n));
  4675. if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
  4676. if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
  4677. if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_RECV_FAILED;
  4678. return (int) n;
  4679. }
  4680. void mg_tls_handshake(struct mg_connection *c) {
  4681. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4682. int rc = mbedtls_ssl_handshake(&tls->ssl);
  4683. if (rc == 0) { // Success
  4684. MG_DEBUG(("%lu success", c->id));
  4685. c->is_tls_hs = 0;
  4686. mg_call(c, MG_EV_TLS_HS, NULL);
  4687. } else if (rc == MBEDTLS_ERR_SSL_WANT_READ ||
  4688. rc == MBEDTLS_ERR_SSL_WANT_WRITE) { // Still pending
  4689. MG_VERBOSE(("%lu pending, %d%d %d (-%#x)", c->id, c->is_connecting,
  4690. c->is_tls_hs, rc, -rc));
  4691. } else {
  4692. mg_error(c, "TLS handshake: -%#x", -rc); // Error
  4693. }
  4694. }
  4695. static int mbed_rng(void *ctx, unsigned char *buf, size_t len) {
  4696. mg_random(buf, len);
  4697. (void) ctx;
  4698. return 0;
  4699. }
  4700. static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) {
  4701. n = (int) strlen(s2) - 1;
  4702. MG_INFO(("%lu %d %.*s", ((struct mg_connection *) c)->id, lev, n, s2));
  4703. (void) s;
  4704. }
  4705. #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
  4706. static int rng_get(void *p_rng, unsigned char *buf, size_t len) {
  4707. (void) p_rng;
  4708. mg_random(buf, len);
  4709. return 0;
  4710. }
  4711. #endif
  4712. static struct mg_str mg_loadfile(struct mg_fs *fs, const char *path) {
  4713. size_t n = 0;
  4714. if (path[0] == '-') return mg_str(path);
  4715. char *p = mg_file_read(fs, path, &n);
  4716. return mg_str_n(p, n);
  4717. }
  4718. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  4719. struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  4720. struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
  4721. int rc = 0;
  4722. c->tls = tls;
  4723. if (c->tls == NULL) {
  4724. mg_error(c, "TLS OOM");
  4725. goto fail;
  4726. }
  4727. MG_DEBUG(("%lu Setting TLS", c->id));
  4728. mbedtls_ssl_init(&tls->ssl);
  4729. mbedtls_ssl_config_init(&tls->conf);
  4730. mbedtls_x509_crt_init(&tls->ca);
  4731. mbedtls_x509_crt_init(&tls->cert);
  4732. mbedtls_pk_init(&tls->pk);
  4733. mbedtls_ssl_conf_dbg(&tls->conf, debug_cb, c);
  4734. #if defined(MG_MBEDTLS_DEBUG_LEVEL)
  4735. mbedtls_debug_set_threshold(MG_MBEDTLS_DEBUG_LEVEL);
  4736. #endif
  4737. if ((rc = mbedtls_ssl_config_defaults(
  4738. &tls->conf,
  4739. c->is_client ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
  4740. MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
  4741. mg_error(c, "tls defaults %#x", -rc);
  4742. goto fail;
  4743. }
  4744. mbedtls_ssl_conf_rng(&tls->conf, mbed_rng, c);
  4745. if (opts->ca == NULL || strcmp(opts->ca, "*") == 0) {
  4746. mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
  4747. } else if (opts->ca != NULL && opts->ca[0] != '\0') {
  4748. #if defined(MBEDTLS_X509_CA_CHAIN_ON_DISK)
  4749. tls->cafile = strdup(opts->ca);
  4750. rc = mbedtls_ssl_conf_ca_chain_file(&tls->conf, tls->cafile, NULL);
  4751. if (rc != 0) {
  4752. mg_error(c, "parse on-disk chain(%s) err %#x", tls->cafile, -rc);
  4753. goto fail;
  4754. }
  4755. #else
  4756. struct mg_str s = mg_loadfile(fs, opts->ca);
  4757. rc = mbedtls_x509_crt_parse(&tls->ca, (uint8_t *) s.ptr, s.len + 1);
  4758. if (opts->ca[0] != '-') free((char *) s.ptr);
  4759. if (rc != 0) {
  4760. mg_error(c, "parse(%s) err %#x", opts->ca, -rc);
  4761. goto fail;
  4762. }
  4763. mbedtls_ssl_conf_ca_chain(&tls->conf, &tls->ca, NULL);
  4764. #endif
  4765. if (opts->srvname.len > 0) {
  4766. char *x = mg_mprintf("%.*s", (int) opts->srvname.len, opts->srvname.ptr);
  4767. mbedtls_ssl_set_hostname(&tls->ssl, x);
  4768. free(x);
  4769. }
  4770. mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
  4771. }
  4772. if (opts->cert != NULL && opts->cert[0] != '\0') {
  4773. struct mg_str s = mg_loadfile(fs, opts->cert);
  4774. const char *key = opts->certkey == NULL ? opts->cert : opts->certkey;
  4775. rc = mbedtls_x509_crt_parse(&tls->cert, (uint8_t *) s.ptr, s.len + 1);
  4776. if (opts->cert[0] != '-') free((char *) s.ptr);
  4777. if (rc != 0) {
  4778. mg_error(c, "parse(%s) err %#x", opts->cert, -rc);
  4779. goto fail;
  4780. }
  4781. s = mg_loadfile(fs, key);
  4782. rc = mbedtls_pk_parse_key(&tls->pk, (uint8_t *) s.ptr, s.len + 1, NULL,
  4783. 0 MGRNG);
  4784. if (key[0] != '-') free((char *) s.ptr);
  4785. if (rc != 0) {
  4786. mg_error(c, "tls key(%s) %#x", key, -rc);
  4787. goto fail;
  4788. }
  4789. rc = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->cert, &tls->pk);
  4790. if (rc != 0) {
  4791. mg_error(c, "own cert %#x", -rc);
  4792. goto fail;
  4793. }
  4794. }
  4795. if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) {
  4796. mg_error(c, "setup err %#x", -rc);
  4797. goto fail;
  4798. }
  4799. c->tls = tls;
  4800. c->is_tls = 1;
  4801. c->is_tls_hs = 1;
  4802. mbedtls_ssl_set_bio(&tls->ssl, c, mg_net_send, mg_net_recv, 0);
  4803. if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
  4804. mg_tls_handshake(c);
  4805. }
  4806. return;
  4807. fail:
  4808. mg_tls_free(c);
  4809. }
  4810. size_t mg_tls_pending(struct mg_connection *c) {
  4811. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4812. return tls == NULL ? 0 : mbedtls_ssl_get_bytes_avail(&tls->ssl);
  4813. }
  4814. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  4815. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4816. long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
  4817. if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
  4818. return MG_IO_WAIT;
  4819. if (n <= 0) return MG_IO_ERR;
  4820. return n;
  4821. }
  4822. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  4823. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4824. long n = mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len);
  4825. if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
  4826. return MG_IO_WAIT;
  4827. if (n <= 0) return MG_IO_ERR;
  4828. return n;
  4829. }
  4830. #endif
  4831. #ifdef MG_ENABLE_LINES
  4832. #line 1 "src/tls_openssl.c"
  4833. #endif
  4834. #if MG_ENABLE_OPENSSL
  4835. static int mg_tls_err(struct mg_tls *tls, int res) {
  4836. int err = SSL_get_error(tls->ssl, res);
  4837. // We've just fetched the last error from the queue.
  4838. // Now we need to clear the error queue. If we do not, then the following
  4839. // can happen (actually reported):
  4840. // - A new connection is accept()-ed with cert error (e.g. self-signed cert)
  4841. // - Since all accept()-ed connections share listener's context,
  4842. // - *ALL* SSL accepted connection report read error on the next poll cycle.
  4843. // Thus a single errored connection can close all the rest, unrelated ones.
  4844. // Clearing the error keeps the shared SSL_CTX in an OK state.
  4845. if (err != 0) ERR_print_errors_fp(stderr);
  4846. ERR_clear_error();
  4847. if (err == SSL_ERROR_WANT_READ) return 0;
  4848. if (err == SSL_ERROR_WANT_WRITE) return 0;
  4849. return err;
  4850. }
  4851. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
  4852. struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
  4853. const char *id = "mongoose";
  4854. static unsigned char s_initialised = 0;
  4855. int rc;
  4856. if (tls == NULL) {
  4857. mg_error(c, "TLS OOM");
  4858. goto fail;
  4859. }
  4860. if (!s_initialised) {
  4861. SSL_library_init();
  4862. s_initialised++;
  4863. }
  4864. MG_DEBUG(("%lu Setting TLS, CA: %s, cert: %s, key: %s", c->id,
  4865. opts->ca == NULL ? "null" : opts->ca,
  4866. opts->cert == NULL ? "null" : opts->cert,
  4867. opts->certkey == NULL ? "null" : opts->certkey));
  4868. tls->ctx = c->is_client ? SSL_CTX_new(SSLv23_client_method())
  4869. : SSL_CTX_new(SSLv23_server_method());
  4870. if ((tls->ssl = SSL_new(tls->ctx)) == NULL) {
  4871. mg_error(c, "SSL_new");
  4872. goto fail;
  4873. }
  4874. SSL_set_session_id_context(tls->ssl, (const uint8_t *) id,
  4875. (unsigned) strlen(id));
  4876. // Disable deprecated protocols
  4877. SSL_set_options(tls->ssl, SSL_OP_NO_SSLv2);
  4878. SSL_set_options(tls->ssl, SSL_OP_NO_SSLv3);
  4879. SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1);
  4880. SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1_1);
  4881. #ifdef MG_ENABLE_OPENSSL_NO_COMPRESSION
  4882. SSL_set_options(tls->ssl, SSL_OP_NO_COMPRESSION);
  4883. #endif
  4884. #ifdef MG_ENABLE_OPENSSL_CIPHER_SERVER_PREFERENCE
  4885. SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
  4886. #endif
  4887. if (opts->ca != NULL && opts->ca[0] != '\0') {
  4888. SSL_set_verify(tls->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
  4889. NULL);
  4890. if ((rc = SSL_CTX_load_verify_locations(tls->ctx, opts->ca, NULL)) != 1) {
  4891. mg_error(c, "load('%s') %d err %d", opts->ca, rc, mg_tls_err(tls, rc));
  4892. goto fail;
  4893. }
  4894. }
  4895. if (opts->cert != NULL && opts->cert[0] != '\0') {
  4896. const char *key = opts->certkey;
  4897. if (key == NULL) key = opts->cert;
  4898. if ((rc = SSL_use_certificate_file(tls->ssl, opts->cert, 1)) != 1) {
  4899. mg_error(c, "Invalid SSL cert, err %d", mg_tls_err(tls, rc));
  4900. goto fail;
  4901. } else if ((rc = SSL_use_PrivateKey_file(tls->ssl, key, 1)) != 1) {
  4902. mg_error(c, "Invalid SSL key, err %d", mg_tls_err(tls, rc));
  4903. goto fail;
  4904. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4905. } else if ((rc = SSL_use_certificate_chain_file(tls->ssl, opts->cert)) !=
  4906. 1) {
  4907. mg_error(c, "Invalid chain, err %d", mg_tls_err(tls, rc));
  4908. goto fail;
  4909. #endif
  4910. } else {
  4911. SSL_set_mode(tls->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  4912. #if OPENSSL_VERSION_NUMBER > 0x10002000L
  4913. SSL_set_ecdh_auto(tls->ssl, 1);
  4914. #endif
  4915. }
  4916. }
  4917. if (opts->ciphers != NULL) SSL_set_cipher_list(tls->ssl, opts->ciphers);
  4918. #if OPENSSL_VERSION_NUMBER >= 0x10100000L
  4919. if (opts->srvname.len > 0) {
  4920. char *s = mg_mprintf("%.*s", (int) opts->srvname.len, opts->srvname.ptr);
  4921. SSL_set1_host(tls->ssl, s);
  4922. SSL_set_tlsext_host_name(tls->ssl, s);
  4923. free(s);
  4924. }
  4925. #endif
  4926. c->tls = tls;
  4927. c->is_tls = 1;
  4928. c->is_tls_hs = 1;
  4929. if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
  4930. mg_tls_handshake(c);
  4931. }
  4932. MG_DEBUG(("%lu SSL %s OK", c->id, c->is_accepted ? "accept" : "client"));
  4933. return;
  4934. fail:
  4935. c->is_closing = 1;
  4936. free(tls);
  4937. }
  4938. void mg_tls_handshake(struct mg_connection *c) {
  4939. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4940. int rc;
  4941. SSL_set_fd(tls->ssl, (int) (size_t) c->fd);
  4942. rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl);
  4943. if (rc == 1) {
  4944. MG_DEBUG(("%lu success", c->id));
  4945. c->is_tls_hs = 0;
  4946. mg_call(c, MG_EV_TLS_HS, NULL);
  4947. } else {
  4948. int code = mg_tls_err(tls, rc);
  4949. if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
  4950. }
  4951. }
  4952. void mg_tls_free(struct mg_connection *c) {
  4953. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4954. if (tls == NULL) return;
  4955. SSL_free(tls->ssl);
  4956. SSL_CTX_free(tls->ctx);
  4957. free(tls);
  4958. c->tls = NULL;
  4959. }
  4960. size_t mg_tls_pending(struct mg_connection *c) {
  4961. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4962. return tls == NULL ? 0 : (size_t) SSL_pending(tls->ssl);
  4963. }
  4964. long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
  4965. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4966. int n = SSL_read(tls->ssl, buf, (int) len);
  4967. if (n < 0 && mg_tls_err(tls, n) == 0) return MG_IO_WAIT;
  4968. if (n <= 0) return MG_IO_ERR;
  4969. return n;
  4970. }
  4971. long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
  4972. struct mg_tls *tls = (struct mg_tls *) c->tls;
  4973. int n = SSL_write(tls->ssl, buf, (int) len);
  4974. if (n < 0 && mg_tls_err(tls, n) == 0) return MG_IO_WAIT;
  4975. if (n <= 0) return MG_IO_ERR;
  4976. return n;
  4977. }
  4978. #endif
  4979. #ifdef MG_ENABLE_LINES
  4980. #line 1 "src/url.c"
  4981. #endif
  4982. struct url {
  4983. size_t key, user, pass, host, port, uri, end;
  4984. };
  4985. int mg_url_is_ssl(const char *url) {
  4986. return strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0 ||
  4987. strncmp(url, "mqtts:", 6) == 0 || strncmp(url, "ssl:", 4) == 0 ||
  4988. strncmp(url, "tls:", 4) == 0;
  4989. }
  4990. static struct url urlparse(const char *url) {
  4991. size_t i;
  4992. struct url u;
  4993. memset(&u, 0, sizeof(u));
  4994. for (i = 0; url[i] != '\0'; i++) {
  4995. if (url[i] == '/' && i > 0 && u.host == 0 && url[i - 1] == '/') {
  4996. u.host = i + 1;
  4997. u.port = 0;
  4998. } else if (url[i] == ']') {
  4999. u.port = 0; // IPv6 URLs, like http://[::1]/bar
  5000. } else if (url[i] == ':' && u.port == 0 && u.uri == 0) {
  5001. u.port = i + 1;
  5002. } else if (url[i] == '@' && u.user == 0 && u.pass == 0 && u.uri == 0) {
  5003. u.user = u.host;
  5004. u.pass = u.port;
  5005. u.host = i + 1;
  5006. u.port = 0;
  5007. } else if (url[i] == '/' && u.host && u.uri == 0) {
  5008. u.uri = i;
  5009. }
  5010. }
  5011. u.end = i;
  5012. #if 0
  5013. printf("[%s] %d %d %d %d %d\n", url, u.user, u.pass, u.host, u.port, u.uri);
  5014. #endif
  5015. return u;
  5016. }
  5017. struct mg_str mg_url_host(const char *url) {
  5018. struct url u = urlparse(url);
  5019. size_t n = u.port ? u.port - u.host - 1
  5020. : u.uri ? u.uri - u.host
  5021. : u.end - u.host;
  5022. struct mg_str s = mg_str_n(url + u.host, n);
  5023. return s;
  5024. }
  5025. const char *mg_url_uri(const char *url) {
  5026. struct url u = urlparse(url);
  5027. return u.uri ? url + u.uri : "/";
  5028. }
  5029. unsigned short mg_url_port(const char *url) {
  5030. struct url u = urlparse(url);
  5031. unsigned short port = 0;
  5032. if (strncmp(url, "http:", 5) == 0 || strncmp(url, "ws:", 3) == 0) port = 80;
  5033. if (strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0)
  5034. port = 443;
  5035. if (strncmp(url, "mqtt:", 5) == 0) port = 1883;
  5036. if (strncmp(url, "mqtts:", 6) == 0) port = 8883;
  5037. if (u.port) port = (unsigned short) atoi(url + u.port);
  5038. return port;
  5039. }
  5040. struct mg_str mg_url_user(const char *url) {
  5041. struct url u = urlparse(url);
  5042. struct mg_str s = mg_str("");
  5043. if (u.user && (u.pass || u.host)) {
  5044. size_t n = u.pass ? u.pass - u.user - 1 : u.host - u.user - 1;
  5045. s = mg_str_n(url + u.user, n);
  5046. }
  5047. return s;
  5048. }
  5049. struct mg_str mg_url_pass(const char *url) {
  5050. struct url u = urlparse(url);
  5051. struct mg_str s = mg_str_n("", 0UL);
  5052. if (u.pass && u.host) {
  5053. size_t n = u.host - u.pass - 1;
  5054. s = mg_str_n(url + u.pass, n);
  5055. }
  5056. return s;
  5057. }
  5058. #ifdef MG_ENABLE_LINES
  5059. #line 1 "src/util.c"
  5060. #endif
  5061. #if MG_ENABLE_CUSTOM_RANDOM
  5062. #else
  5063. void mg_random(void *buf, size_t len) {
  5064. bool done = false;
  5065. unsigned char *p = (unsigned char *) buf;
  5066. #if MG_ARCH == MG_ARCH_ESP32
  5067. while (len--) *p++ = (unsigned char) (esp_random() & 255);
  5068. done = true;
  5069. #elif MG_ARCH == MG_ARCH_WIN32
  5070. #elif MG_ARCH == MG_ARCH_UNIX
  5071. FILE *fp = fopen("/dev/urandom", "rb");
  5072. if (fp != NULL) {
  5073. if (fread(buf, 1, len, fp) == len) done = true;
  5074. fclose(fp);
  5075. }
  5076. #endif
  5077. // If everything above did not work, fallback to a pseudo random generator
  5078. while (!done && len--) *p++ = (unsigned char) (rand() & 255);
  5079. }
  5080. #endif
  5081. char *mg_random_str(char *buf, size_t len) {
  5082. size_t i;
  5083. mg_random(buf, len);
  5084. for (i = 0; i < len; i++) {
  5085. uint8_t c = ((uint8_t *) buf)[i] % 62U;
  5086. buf[i] = i == len - 1 ? (char) '\0' // 0-terminate last byte
  5087. : c < 26 ? (char) ('a' + c) // lowercase
  5088. : c < 52 ? (char) ('A' + c - 26) // uppercase
  5089. : (char) ('0' + c - 52); // numeric
  5090. }
  5091. return buf;
  5092. }
  5093. uint32_t mg_ntohl(uint32_t net) {
  5094. uint8_t data[4] = {0, 0, 0, 0};
  5095. memcpy(&data, &net, sizeof(data));
  5096. return (((uint32_t) data[3]) << 0) | (((uint32_t) data[2]) << 8) |
  5097. (((uint32_t) data[1]) << 16) | (((uint32_t) data[0]) << 24);
  5098. }
  5099. uint16_t mg_ntohs(uint16_t net) {
  5100. uint8_t data[2] = {0, 0};
  5101. memcpy(&data, &net, sizeof(data));
  5102. return (uint16_t) ((uint16_t) data[1] | (((uint16_t) data[0]) << 8));
  5103. }
  5104. uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len) {
  5105. static const uint32_t crclut[16] = {
  5106. // table for polynomial 0xEDB88320 (reflected)
  5107. 0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4,
  5108. 0x4DB26158, 0x5005713C, 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
  5109. 0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C};
  5110. crc = ~crc;
  5111. while (len--) {
  5112. uint8_t byte = *(uint8_t *)buf++;
  5113. crc = crclut[(crc ^ byte) & 0x0F] ^ (crc >> 4);
  5114. crc = crclut[(crc ^ (byte >> 4)) & 0x0F] ^ (crc >> 4);
  5115. }
  5116. return ~crc;
  5117. }
  5118. static int isbyte(int n) {
  5119. return n >= 0 && n <= 255;
  5120. }
  5121. static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
  5122. int n, a, b, c, d, slash = 32, len = 0;
  5123. if ((sscanf(spec, "%d.%d.%d.%d/%d%n", &a, &b, &c, &d, &slash, &n) == 5 ||
  5124. sscanf(spec, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4) &&
  5125. isbyte(a) && isbyte(b) && isbyte(c) && isbyte(d) && slash >= 0 &&
  5126. slash < 33) {
  5127. len = n;
  5128. *net = ((uint32_t) a << 24) | ((uint32_t) b << 16) | ((uint32_t) c << 8) |
  5129. (uint32_t) d;
  5130. *mask = slash ? (uint32_t) (0xffffffffU << (32 - slash)) : (uint32_t) 0;
  5131. }
  5132. return len;
  5133. }
  5134. int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip) {
  5135. struct mg_str k, v;
  5136. int allowed = acl.len == 0 ? '+' : '-'; // If any ACL is set, deny by default
  5137. while (mg_commalist(&acl, &k, &v)) {
  5138. uint32_t net, mask;
  5139. if (k.ptr[0] != '+' && k.ptr[0] != '-') return -1;
  5140. if (parse_net(&k.ptr[1], &net, &mask) == 0) return -2;
  5141. if ((mg_ntohl(remote_ip) & mask) == net) allowed = k.ptr[0];
  5142. }
  5143. return allowed == '+';
  5144. }
  5145. #if MG_ENABLE_CUSTOM_MILLIS
  5146. #else
  5147. uint64_t mg_millis(void) {
  5148. #if MG_ARCH == MG_ARCH_WIN32
  5149. return GetTickCount();
  5150. #elif MG_ARCH == MG_ARCH_RP2040
  5151. return time_us_64() / 1000;
  5152. #elif MG_ARCH == MG_ARCH_ESP32
  5153. return esp_timer_get_time() / 1000;
  5154. #elif MG_ARCH == MG_ARCH_ESP8266 || MG_ARCH == MG_ARCH_FREERTOS
  5155. return xTaskGetTickCount() * portTICK_PERIOD_MS;
  5156. #elif MG_ARCH == MG_ARCH_AZURERTOS
  5157. return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND);
  5158. #elif MG_ARCH == MG_ARCH_TIRTOS
  5159. return (uint64_t) Clock_getTicks();
  5160. #elif MG_ARCH == MG_ARCH_ZEPHYR
  5161. return (uint64_t) k_uptime_get();
  5162. #elif MG_ARCH == MG_ARCH_CMSIS_RTOS1
  5163. return (uint64_t)rt_time_get();
  5164. #elif MG_ARCH == MG_ARCH_CMSIS_RTOS2
  5165. return (uint64_t)((osKernelGetTickCount() * 1000) / osKernelGetTickFreq());
  5166. #elif MG_ARCH == MG_ARCH_UNIX && defined(__APPLE__)
  5167. // Apple CLOCK_MONOTONIC_RAW is equivalent to CLOCK_BOOTTIME on linux
  5168. // Apple CLOCK_UPTIME_RAW is equivalent to CLOCK_MONOTONIC_RAW on linux
  5169. return clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1000000;
  5170. #elif MG_ARCH == MG_ARCH_UNIX
  5171. struct timespec ts = {0, 0};
  5172. // See #1615 - prefer monotonic clock
  5173. #if defined(CLOCK_MONOTONIC_RAW)
  5174. // Raw hardware-based time that is not subject to NTP adjustment
  5175. clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
  5176. #elif defined(CLOCK_MONOTONIC)
  5177. // Affected by the incremental adjustments performed by adjtime and NTP
  5178. clock_gettime(CLOCK_MONOTONIC, &ts);
  5179. #else
  5180. // Affected by discontinuous jumps in the system time and by the incremental
  5181. // adjustments performed by adjtime and NTP
  5182. clock_gettime(CLOCK_REALTIME, &ts);
  5183. #endif
  5184. return ((uint64_t) ts.tv_sec * 1000 + (uint64_t) ts.tv_nsec / 1000000);
  5185. #elif defined(ARDUINO)
  5186. return (uint64_t) millis();
  5187. #else
  5188. return (uint64_t) (time(NULL) * 1000);
  5189. #endif
  5190. }
  5191. #endif
  5192. #ifdef MG_ENABLE_LINES
  5193. #line 1 "src/ws.c"
  5194. #endif
  5195. struct ws_msg {
  5196. uint8_t flags;
  5197. size_t header_len;
  5198. size_t data_len;
  5199. };
  5200. size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
  5201. va_list *ap) {
  5202. size_t len = c->send.len;
  5203. size_t n = mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  5204. mg_ws_wrap(c, c->send.len - len, op);
  5205. return n;
  5206. }
  5207. size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...) {
  5208. size_t len = 0;
  5209. va_list ap;
  5210. va_start(ap, fmt);
  5211. len = mg_ws_vprintf(c, op, fmt, &ap);
  5212. va_end(ap);
  5213. return len;
  5214. }
  5215. static void ws_handshake(struct mg_connection *c, const struct mg_str *wskey,
  5216. const struct mg_str *wsproto, const char *fmt,
  5217. va_list *ap) {
  5218. const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
  5219. unsigned char sha[20], b64_sha[30];
  5220. mg_sha1_ctx sha_ctx;
  5221. mg_sha1_init(&sha_ctx);
  5222. mg_sha1_update(&sha_ctx, (unsigned char *) wskey->ptr, wskey->len);
  5223. mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
  5224. mg_sha1_final(sha, &sha_ctx);
  5225. mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
  5226. mg_xprintf(mg_pfn_iobuf, &c->send,
  5227. "HTTP/1.1 101 Switching Protocols\r\n"
  5228. "Upgrade: websocket\r\n"
  5229. "Connection: Upgrade\r\n"
  5230. "Sec-WebSocket-Accept: %s\r\n",
  5231. b64_sha);
  5232. if (fmt != NULL) mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
  5233. if (wsproto != NULL) {
  5234. mg_printf(c, "Sec-WebSocket-Protocol: %.*s\r\n", (int) wsproto->len,
  5235. wsproto->ptr);
  5236. }
  5237. mg_send(c, "\r\n", 2);
  5238. }
  5239. static uint32_t be32(const uint8_t *p) {
  5240. return (((uint32_t) p[3]) << 0) | (((uint32_t) p[2]) << 8) |
  5241. (((uint32_t) p[1]) << 16) | (((uint32_t) p[0]) << 24);
  5242. }
  5243. static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
  5244. size_t i, n = 0, mask_len = 0;
  5245. memset(msg, 0, sizeof(*msg));
  5246. if (len >= 2) {
  5247. n = buf[1] & 0x7f; // Frame length
  5248. mask_len = buf[1] & 128 ? 4 : 0; // last bit is a mask bit
  5249. msg->flags = buf[0];
  5250. if (n < 126 && len >= mask_len) {
  5251. msg->data_len = n;
  5252. msg->header_len = 2 + mask_len;
  5253. } else if (n == 126 && len >= 4 + mask_len) {
  5254. msg->header_len = 4 + mask_len;
  5255. msg->data_len = (((size_t) buf[2]) << 8) | buf[3];
  5256. } else if (len >= 10 + mask_len) {
  5257. msg->header_len = 10 + mask_len;
  5258. msg->data_len =
  5259. (size_t) (((uint64_t) be32(buf + 2) << 32) + be32(buf + 6));
  5260. }
  5261. }
  5262. // Sanity check, and integer overflow protection for the boundary check below
  5263. // data_len should not be larger than 1 Gb
  5264. if (msg->data_len > 1024 * 1024 * 1024) return 0;
  5265. if (msg->header_len + msg->data_len > len) return 0;
  5266. if (mask_len > 0) {
  5267. uint8_t *p = buf + msg->header_len, *m = p - mask_len;
  5268. for (i = 0; i < msg->data_len; i++) p[i] ^= m[i & 3];
  5269. }
  5270. return msg->header_len + msg->data_len;
  5271. }
  5272. static size_t mkhdr(size_t len, int op, bool is_client, uint8_t *buf) {
  5273. size_t n = 0;
  5274. buf[0] = (uint8_t) (op | 128);
  5275. if (len < 126) {
  5276. buf[1] = (unsigned char) len;
  5277. n = 2;
  5278. } else if (len < 65536) {
  5279. uint16_t tmp = mg_htons((uint16_t) len);
  5280. buf[1] = 126;
  5281. memcpy(&buf[2], &tmp, sizeof(tmp));
  5282. n = 4;
  5283. } else {
  5284. uint32_t tmp;
  5285. buf[1] = 127;
  5286. tmp = mg_htonl((uint32_t) (((uint64_t) len) >> 32));
  5287. memcpy(&buf[2], &tmp, sizeof(tmp));
  5288. tmp = mg_htonl((uint32_t) (len & 0xffffffffU));
  5289. memcpy(&buf[6], &tmp, sizeof(tmp));
  5290. n = 10;
  5291. }
  5292. if (is_client) {
  5293. buf[1] |= 1 << 7; // Set masking flag
  5294. mg_random(&buf[n], 4);
  5295. n += 4;
  5296. }
  5297. return n;
  5298. }
  5299. static void mg_ws_mask(struct mg_connection *c, size_t len) {
  5300. if (c->is_client && c->send.buf != NULL) {
  5301. size_t i;
  5302. uint8_t *p = c->send.buf + c->send.len - len, *mask = p - 4;
  5303. for (i = 0; i < len; i++) p[i] ^= mask[i & 3];
  5304. }
  5305. }
  5306. size_t mg_ws_send(struct mg_connection *c, const void *buf, size_t len,
  5307. int op) {
  5308. uint8_t header[14];
  5309. size_t header_len = mkhdr(len, op, c->is_client, header);
  5310. mg_send(c, header, header_len);
  5311. MG_VERBOSE(("WS out: %d [%.*s]", (int) len, (int) len, buf));
  5312. mg_send(c, buf, len);
  5313. mg_ws_mask(c, len);
  5314. return header_len + len;
  5315. }
  5316. static bool mg_ws_client_handshake(struct mg_connection *c) {
  5317. int n = mg_http_get_request_len(c->recv.buf, c->recv.len);
  5318. if (n < 0) {
  5319. mg_error(c, "not http"); // Some just, not an HTTP request
  5320. } else if (n > 0) {
  5321. if (n < 15 || memcmp(c->recv.buf + 9, "101", 3) != 0) {
  5322. mg_error(c, "handshake error");
  5323. } else {
  5324. struct mg_http_message hm;
  5325. mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
  5326. c->is_websocket = 1;
  5327. mg_call(c, MG_EV_WS_OPEN, &hm);
  5328. }
  5329. mg_iobuf_del(&c->recv, 0, (size_t) n);
  5330. } else {
  5331. return true; // Request is not yet received, quit event handler
  5332. }
  5333. return false; // Continue event handler
  5334. }
  5335. static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
  5336. void *fn_data) {
  5337. struct ws_msg msg;
  5338. size_t ofs = (size_t) c->pfn_data;
  5339. // assert(ofs < c->recv.len);
  5340. if (ev == MG_EV_READ) {
  5341. if (c->is_client && !c->is_websocket && mg_ws_client_handshake(c)) return;
  5342. while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) {
  5343. char *s = (char *) c->recv.buf + ofs + msg.header_len;
  5344. struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
  5345. size_t len = msg.header_len + msg.data_len;
  5346. uint8_t final = msg.flags & 128, op = msg.flags & 15;
  5347. // MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op,
  5348. // (int) m.data.len, (int) m.data.len, m.data.ptr));
  5349. switch (op) {
  5350. case WEBSOCKET_OP_CONTINUE:
  5351. mg_call(c, MG_EV_WS_CTL, &m);
  5352. break;
  5353. case WEBSOCKET_OP_PING:
  5354. MG_DEBUG(("%s", "WS PONG"));
  5355. mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG);
  5356. mg_call(c, MG_EV_WS_CTL, &m);
  5357. break;
  5358. case WEBSOCKET_OP_PONG:
  5359. mg_call(c, MG_EV_WS_CTL, &m);
  5360. break;
  5361. case WEBSOCKET_OP_TEXT:
  5362. case WEBSOCKET_OP_BINARY:
  5363. if (final) mg_call(c, MG_EV_WS_MSG, &m);
  5364. break;
  5365. case WEBSOCKET_OP_CLOSE:
  5366. MG_DEBUG(("%lu WS CLOSE", c->id));
  5367. mg_call(c, MG_EV_WS_CTL, &m);
  5368. // Echo the payload of the received CLOSE message back to the sender
  5369. mg_ws_send(c, m.data.ptr, m.data.len, WEBSOCKET_OP_CLOSE);
  5370. c->is_draining = 1;
  5371. break;
  5372. default:
  5373. // Per RFC6455, close conn when an unknown op is recvd
  5374. mg_error(c, "unknown WS op %d", op);
  5375. break;
  5376. }
  5377. // Handle fragmented frames: strip header, keep in c->recv
  5378. if (final == 0 || op == 0) {
  5379. if (op) ofs++, len--, msg.header_len--; // First frame
  5380. mg_iobuf_del(&c->recv, ofs, msg.header_len); // Strip header
  5381. len -= msg.header_len;
  5382. ofs += len;
  5383. c->pfn_data = (void *) ofs;
  5384. // MG_INFO(("FRAG %d [%.*s]", (int) ofs, (int) ofs, c->recv.buf));
  5385. }
  5386. // Remove non-fragmented frame
  5387. if (final && op) mg_iobuf_del(&c->recv, ofs, len);
  5388. // Last chunk of the fragmented frame
  5389. if (final && !op) {
  5390. m.flags = c->recv.buf[0];
  5391. m.data = mg_str_n((char *) &c->recv.buf[1], (size_t) (ofs - 1));
  5392. mg_call(c, MG_EV_WS_MSG, &m);
  5393. mg_iobuf_del(&c->recv, 0, ofs);
  5394. ofs = 0;
  5395. c->pfn_data = NULL;
  5396. }
  5397. }
  5398. }
  5399. (void) fn_data;
  5400. (void) ev_data;
  5401. }
  5402. struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
  5403. mg_event_handler_t fn, void *fn_data,
  5404. const char *fmt, ...) {
  5405. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  5406. if (c != NULL) {
  5407. char nonce[16], key[30];
  5408. struct mg_str host = mg_url_host(url);
  5409. mg_random(nonce, sizeof(nonce));
  5410. mg_base64_encode((unsigned char *) nonce, sizeof(nonce), key);
  5411. mg_xprintf(mg_pfn_iobuf, &c->send,
  5412. "GET %s HTTP/1.1\r\n"
  5413. "Upgrade: websocket\r\n"
  5414. "Host: %.*s\r\n"
  5415. "Connection: Upgrade\r\n"
  5416. "Sec-WebSocket-Version: 13\r\n"
  5417. "Sec-WebSocket-Key: %s\r\n",
  5418. mg_url_uri(url), (int) host.len, host.ptr, key);
  5419. if (fmt != NULL) {
  5420. va_list ap;
  5421. va_start(ap, fmt);
  5422. mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
  5423. va_end(ap);
  5424. }
  5425. mg_xprintf(mg_pfn_iobuf, &c->send, "\r\n");
  5426. c->pfn = mg_ws_cb;
  5427. c->pfn_data = NULL;
  5428. }
  5429. return c;
  5430. }
  5431. void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm,
  5432. const char *fmt, ...) {
  5433. struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
  5434. c->pfn = mg_ws_cb;
  5435. c->pfn_data = NULL;
  5436. if (wskey == NULL) {
  5437. mg_http_reply(c, 426, "", "WS upgrade expected\n");
  5438. c->is_draining = 1;
  5439. } else {
  5440. struct mg_str *wsproto = mg_http_get_header(hm, "Sec-WebSocket-Protocol");
  5441. va_list ap;
  5442. va_start(ap, fmt);
  5443. ws_handshake(c, wskey, wsproto, fmt, &ap);
  5444. va_end(ap);
  5445. c->is_websocket = 1;
  5446. c->is_resp = 0;
  5447. mg_call(c, MG_EV_WS_OPEN, hm);
  5448. }
  5449. }
  5450. size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
  5451. uint8_t header[14], *p;
  5452. size_t header_len = mkhdr(len, op, c->is_client, header);
  5453. // NOTE: order of operations is important!
  5454. mg_iobuf_add(&c->send, c->send.len, NULL, header_len);
  5455. p = &c->send.buf[c->send.len - len]; // p points to data
  5456. memmove(p, p - header_len, len); // Shift data
  5457. memcpy(p - header_len, header, header_len); // Prepend header
  5458. mg_ws_mask(c, len); // Mask data
  5459. return c->send.len;
  5460. }
  5461. #ifdef MG_ENABLE_LINES
  5462. #line 1 "src/tcpip/driver_nxpimxrt1020.c"
  5463. #endif
  5464. /*
  5465. * Todo
  5466. * This driver doesn't support 10M line autoconfiguration yet.
  5467. * Packets aren't sent if the link negociated 10M line.
  5468. * todo: MAC back auto reconfiguration.
  5469. */
  5470. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_IMXRT1020)
  5471. struct imx_rt1020_enet {
  5472. volatile uint32_t RESERVED0, EIR, EIMR, RESERVED1, RDAR, TDAR, RESERVED2[3], ECR, RESERVED3[6], MMFR, MSCR, RESERVED4[7], MIBC, RESERVED5[7], RCR, RESERVED6[15], TCR, RESERVED7[7], PALR, PAUR, OPD, TXIC0, TXIC1, TXIC2, RESERVED8, RXIC0, RXIC1, RXIC2, RESERVED9[3], IAUR, IALR, GAUR, GALR, RESERVED10[7], TFWR, RESERVED11[14], RDSR, TDSR, MRBR[2], RSFL, RSEM, RAEM, RAFL, TSEM, TAEM, TAFL, TIPG, FTRL, RESERVED12[3], TACC, RACC, RESERVED13[15], RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT, RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG, RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255, RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2048, RMON_T_GTE2048, RMON_T_OCTETS, IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL, IEEE_T_DEF, IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR, IEEE_T_SQE, IEEE_T_FDXFC, IEEE_T_OCTETS_OK, RESERVED14[3], RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN, RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB, RESERVED15, RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255, RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047, RMON_R_GTE2048, RMON_R_OCTETS, IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR, IEEE_R_FDXFC, IEEE_R_OCTETS_OK, RESERVED16[71], ATCR, ATVR, ATOFF, ATPER, ATCOR, ATINC, ATSTMP, RESERVED17[122], TGSR, TCSR0, TCCR0, TCSR1, TCCR1, TCSR2, TCCR2, TCSR3;
  5473. };
  5474. #undef ENET
  5475. #define ENET ((struct imx_rt1020_enet *) (uintptr_t) 0x402D8000u)
  5476. #undef BIT
  5477. #define BIT(x) ((uint32_t) 1 << (x))
  5478. #define ENET_RXBUFF_SIZE 1536 // 1522 Buffer must be 64bits aligned
  5479. #define ENET_TXBUFF_SIZE 1536 // 1522 hence set to 0x600 (1536)
  5480. #define ENET_RXBD_NUM (4)
  5481. #define ENET_TXBD_NUM (4)
  5482. const uint32_t EIMR_RX_ERR = 0x2400000; // Intr mask RXF+EBERR
  5483. void ETH_IRQHandler(void);
  5484. static bool mg_tcpip_driver_imxrt1020_init(struct mg_tcpip_if *ifp);
  5485. static void wait_phy_complete(void);
  5486. static struct mg_tcpip_if *s_ifp; // MIP interface
  5487. static size_t mg_tcpip_driver_imxrt1020_tx(const void *, size_t , struct mg_tcpip_if *);
  5488. static bool mg_tcpip_driver_imxrt1020_up(struct mg_tcpip_if *ifp);
  5489. enum { IMXRT1020_PHY_ADDR = 0x02, IMXRT1020_PHY_BCR = 0, IMXRT1020_PHY_BSR = 1 }; // PHY constants
  5490. void delay(uint32_t);
  5491. void delay (uint32_t di) {
  5492. volatile int dno = 0; // Prevent optimization
  5493. for (uint32_t i = 0; i < di; i++)
  5494. for (int j=0; j<20; j++) // PLLx20 (500 MHz/24MHz)
  5495. dno++;
  5496. }
  5497. static void wait_phy_complete(void) {
  5498. delay(0x00010000);
  5499. const uint32_t delay_max = 0x00100000;
  5500. uint32_t delay_cnt = 0;
  5501. while (!(ENET->EIR & BIT(23)) && (delay_cnt < delay_max))
  5502. {delay_cnt++;}
  5503. ENET->EIR |= BIT(23); // MII interrupt clear
  5504. }
  5505. static uint32_t imxrt1020_eth_read_phy(uint8_t addr, uint8_t reg) {
  5506. ENET->EIR |= BIT(23); // MII interrupt clear
  5507. uint32_t mask_phy_adr_reg = 0x1f; // 0b00011111: Ensure we write 5 bits (Phy address & register)
  5508. uint32_t phy_transaction = 0x00;
  5509. phy_transaction = (0x1 << 30) \
  5510. | (0x2 << 28) \
  5511. | ((uint32_t)(addr & mask_phy_adr_reg) << 23) \
  5512. | ((uint32_t)(reg & mask_phy_adr_reg) << 18) \
  5513. | (0x2 << 16);
  5514. ENET->MMFR = phy_transaction;
  5515. wait_phy_complete();
  5516. return (ENET->MMFR & 0x0000ffff);
  5517. }
  5518. static void imxrt1020_eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
  5519. ENET->EIR |= BIT(23); // MII interrupt clear
  5520. uint8_t mask_phy_adr_reg = 0x1f; // 0b00011111: Ensure we write 5 bits (Phy address & register)
  5521. uint32_t mask_phy_data = 0x0000ffff; // Ensure we write 16 bits (data)
  5522. addr &= mask_phy_adr_reg;
  5523. reg &= mask_phy_adr_reg;
  5524. val &= mask_phy_data;
  5525. uint32_t phy_transaction = 0x00;
  5526. phy_transaction = (uint32_t)(0x1 << 30) \
  5527. | (uint32_t)(0x1 << 28) \
  5528. | (uint32_t)(addr << 23) \
  5529. | (uint32_t)(reg << 18) \
  5530. | (uint32_t)(0x2 << 16) \
  5531. | (uint32_t)(val);
  5532. ENET->MMFR = phy_transaction;
  5533. wait_phy_complete();
  5534. }
  5535. // FEC RX/TX descriptors (Enhanced descriptor not enabled)
  5536. // Descriptor buffer structure, little endian
  5537. typedef struct enet_bd_struct_def
  5538. {
  5539. uint16_t length; // Data length
  5540. uint16_t control; // Control and status
  5541. uint32_t *buffer; // Data ptr
  5542. } enet_bd_struct_t;
  5543. // Descriptor and buffer globals, in non-cached area, 64 bits aligned.
  5544. __attribute__((section("NonCacheable,\"aw\",%nobits @"))) enet_bd_struct_t rx_buffer_descriptor[(ENET_RXBD_NUM)] __attribute__((aligned((64U))));
  5545. __attribute__((section("NonCacheable,\"aw\",%nobits @"))) enet_bd_struct_t tx_buffer_descriptor[(ENET_TXBD_NUM)] __attribute__((aligned((64U))));
  5546. uint8_t rx_data_buffer[(ENET_RXBD_NUM)][((unsigned int)(((ENET_RXBUFF_SIZE)) + (((64U))-1U)) & (unsigned int)(~(unsigned int)(((64U))-1U)))] __attribute__((aligned((64U))));
  5547. uint8_t tx_data_buffer[(ENET_TXBD_NUM)][((unsigned int)(((ENET_TXBUFF_SIZE)) + (((64U))-1U)) & (unsigned int)(~(unsigned int)(((64U))-1U)))] __attribute__((aligned((64U))));
  5548. // Initialise driver imx_rt1020
  5549. // static bool mg_tcpip_driver_imxrt1020_init(uint8_t *mac, void *data) { // VO
  5550. static bool mg_tcpip_driver_imxrt1020_init(struct mg_tcpip_if *ifp) {
  5551. struct mg_tcpip_driver_imxrt1020_data *d = (struct mg_tcpip_driver_imxrt1020_data *) ifp->driver_data;
  5552. s_ifp = ifp;
  5553. // ENET Reset, wait complete
  5554. ENET->ECR |= BIT(0);
  5555. while((ENET->ECR & BIT(0)) != 0) {}
  5556. // Re-latches the pin strapping pin values
  5557. ENET->ECR |= BIT(0);
  5558. while((ENET->ECR & BIT(0)) != 0) {}
  5559. // Setup MII/RMII MDC clock divider (<= 2.5MHz).
  5560. ENET->MSCR = 0x130; // HOLDTIME 2 clk, Preamble enable, MDC MII_Speed Div 0x30
  5561. imxrt1020_eth_write_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BCR, 0x8000); // PHY W @0x00 D=0x8000 Soft reset
  5562. while (imxrt1020_eth_read_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BSR) & BIT(15)) {delay(0x5000);} // Wait finished poll 10ms
  5563. // PHY: Start Link
  5564. {
  5565. imxrt1020_eth_write_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BCR, 0x1200); // PHY W @0x00 D=0x1200 Autonego enable + start
  5566. imxrt1020_eth_write_phy(IMXRT1020_PHY_ADDR, 0x1f, 0x8180); // PHY W @0x1f D=0x8180 Ref clock 50 MHz at XI input
  5567. uint32_t bcr = imxrt1020_eth_read_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BCR);
  5568. bcr &= ~BIT(10); // Isolation -> Normal
  5569. imxrt1020_eth_write_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BCR, bcr);
  5570. }
  5571. // Disable ENET
  5572. ENET->ECR = 0x0; // Disable before configuration
  5573. // Configure ENET
  5574. ENET->RCR = 0x05ee0104; // #CRCFWD=0 (CRC kept in frame) + RMII + MII Enable
  5575. ENET->TCR = BIT(8) | BIT(2); // Addins (MAC address from PAUR+PALR) + Full duplex enable
  5576. //ENET->TFWR = BIT(8); // Store And Forward Enable, 64 bytes (minimize tx latency)
  5577. // Configure descriptors and buffers
  5578. // RX
  5579. for (int i = 0; i < ENET_RXBD_NUM; i++) {
  5580. // Wrap last descriptor buffer ptr
  5581. rx_buffer_descriptor[i].control = (BIT(15) | ((i<(ENET_RXBD_NUM-1))?0:BIT(13))); // E+(W*)
  5582. rx_buffer_descriptor[i].buffer = (uint32_t *)rx_data_buffer[i];
  5583. }
  5584. // TX
  5585. for (int i = 0; i < ENET_TXBD_NUM; i++) {
  5586. // Wrap last descriptor buffer ptr
  5587. tx_buffer_descriptor[i].control = ((i<(ENET_RXBD_NUM-1))?0:BIT(13)) | BIT(10); // (W*)+TC
  5588. tx_buffer_descriptor[i].buffer = (uint32_t *)tx_data_buffer[i];
  5589. }
  5590. // Continue ENET configuration
  5591. ENET->RDSR = (uint32_t)(uintptr_t)rx_buffer_descriptor;
  5592. ENET->TDSR = (uint32_t)(uintptr_t)tx_buffer_descriptor;
  5593. ENET->MRBR[0] = ENET_RXBUFF_SIZE; // Same size for RX/TX buffers
  5594. // MAC address filtering (bytes in reversed order)
  5595. ENET->PAUR = ((uint32_t) ifp->mac[4] << 24U) | (uint32_t) ifp->mac[5] << 16U;
  5596. ENET->PALR = (uint32_t) (ifp->mac[0] << 24U) | ((uint32_t) ifp->mac[1] << 16U) |
  5597. ((uint32_t) ifp->mac[2] << 8U) | ifp->mac[3];
  5598. // Init Hash tables (mac filtering)
  5599. ENET->IAUR = 0; // Unicast
  5600. ENET->IALR = 0;
  5601. ENET->GAUR = 0; // Multicast
  5602. ENET->GALR = 0;
  5603. // Set ENET Online
  5604. ENET->ECR |= BIT(8); // ENET Set Little-endian + (FEC buffer desc.)
  5605. ENET->ECR |= BIT(1); // Enable
  5606. // Set interrupt mask
  5607. ENET->EIMR = EIMR_RX_ERR;
  5608. // RX Descriptor activation
  5609. ENET->RDAR = BIT(24); // Activate Receive Descriptor
  5610. return true;
  5611. }
  5612. // Transmit frame
  5613. static uint32_t s_rt1020_txno;
  5614. static size_t mg_tcpip_driver_imxrt1020_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
  5615. if (len > sizeof(tx_data_buffer[ENET_TXBD_NUM])) {
  5616. // MG_ERROR(("Frame too big, %ld", (long) len));
  5617. len = 0; // Frame is too big
  5618. } else if ((tx_buffer_descriptor[s_rt1020_txno].control & BIT(15))) {
  5619. MG_ERROR(("No free descriptors"));
  5620. // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) ETH->DMASR);
  5621. len = 0; // All descriptors are busy, fail
  5622. } else {
  5623. memcpy(tx_data_buffer[s_rt1020_txno], buf, len); // Copy data
  5624. tx_buffer_descriptor[s_rt1020_txno].length = (uint16_t) len; // Set data len
  5625. tx_buffer_descriptor[s_rt1020_txno].control |= (uint16_t)(BIT(10)); // TC (transmit CRC)
  5626. // tx_buffer_descriptor[s_rt1020_txno].control &= (uint16_t)(BIT(14) | BIT(12)); // Own doesn't affect HW
  5627. tx_buffer_descriptor[s_rt1020_txno].control |= (uint16_t)(BIT(15) | BIT(11)); // R+L (ready+last)
  5628. ENET->TDAR = BIT(24); // Descriptor updated. Hand over to DMA.
  5629. // INFO
  5630. // Relevant Descriptor bits: 15(R) Ready
  5631. // 11(L) last in frame
  5632. // 10(TC) transmis CRC
  5633. // __DSB(); // ARM errata 838869 Cortex-M4, M4F, M7, M7F: "store immediate overlapping
  5634. // exception" return might vector to incorrect interrupt.
  5635. if (++s_rt1020_txno >= ENET_TXBD_NUM) s_rt1020_txno = 0;
  5636. }
  5637. (void) ifp;
  5638. return len;
  5639. }
  5640. // IRQ (RX)
  5641. static uint32_t s_rt1020_rxno;
  5642. void ENET_IRQHandler(void) {
  5643. ENET->EIMR = 0; // Mask interrupts.
  5644. uint32_t eir = ENET->EIR; // Read EIR
  5645. ENET->EIR = 0xffffffff; // Clear interrupts
  5646. if (eir & EIMR_RX_ERR) // Global mask used
  5647. {
  5648. if (rx_buffer_descriptor[s_rt1020_rxno].control & BIT(15)) {
  5649. ENET->EIMR = EIMR_RX_ERR; // Enable interrupts
  5650. return; // Empty? -> exit.
  5651. }
  5652. // Read inframes
  5653. else { // Frame received, loop
  5654. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  5655. if (rx_buffer_descriptor[s_rt1020_rxno].control & BIT(15)) break; // exit when done
  5656. // Process if CRC OK and frame not truncated
  5657. if (!(rx_buffer_descriptor[s_rt1020_rxno].control & (BIT(2) | BIT(0)))) {
  5658. uint32_t len = (rx_buffer_descriptor[s_rt1020_rxno].length);
  5659. mg_tcpip_qwrite(rx_buffer_descriptor[s_rt1020_rxno].buffer, len > 4 ? len - 4 : len, s_ifp);
  5660. }
  5661. rx_buffer_descriptor[s_rt1020_rxno].control |= BIT(15); // Inform DMA RX is empty
  5662. if (++s_rt1020_rxno >= ENET_RXBD_NUM) s_rt1020_rxno = 0;
  5663. }
  5664. }
  5665. }
  5666. ENET->EIMR = EIMR_RX_ERR; // Enable interrupts
  5667. }
  5668. // Up/down status
  5669. static bool mg_tcpip_driver_imxrt1020_up(struct mg_tcpip_if *ifp) {
  5670. uint32_t bsr = imxrt1020_eth_read_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BSR);
  5671. (void) ifp;
  5672. return bsr & BIT(2) ? 1 : 0;
  5673. }
  5674. // API
  5675. struct mg_tcpip_driver mg_tcpip_driver_imxrt1020 = {
  5676. mg_tcpip_driver_imxrt1020_init, mg_tcpip_driver_imxrt1020_tx, NULL,
  5677. mg_tcpip_driver_imxrt1020_up};
  5678. #endif
  5679. #ifdef MG_ENABLE_LINES
  5680. #line 1 "src/tcpip/driver_stm32.c"
  5681. #endif
  5682. #if MG_ENABLE_TCPIP && MG_ENABLE_DRIVER_STM32
  5683. struct stm32_eth {
  5684. volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR,
  5685. MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR,
  5686. MACIMR, MACA0HR, MACA0LR, MACA1HR, MACA1LR, MACA2HR, MACA2LR, MACA3HR,
  5687. MACA3LR, RESERVED2[40], MMCCR, MMCRIR, MMCTIR, MMCRIMR, MMCTIMR,
  5688. RESERVED3[14], MMCTGFSCCR, MMCTGFMSCCR, RESERVED4[5], MMCTGFCR,
  5689. RESERVED5[10], MMCRFCECR, MMCRFAECR, RESERVED6[10], MMCRGUFCR,
  5690. RESERVED7[334], PTPTSCR, PTPSSIR, PTPTSHR, PTPTSLR, PTPTSHUR, PTPTSLUR,
  5691. PTPTSAR, PTPTTHR, PTPTTLR, RESERVED8, PTPTSSR, PTPPPSCR, RESERVED9[564],
  5692. DMABMR, DMATPDR, DMARPDR, DMARDLAR, DMATDLAR, DMASR, DMAOMR, DMAIER,
  5693. DMAMFBOCR, DMARSWTR, RESERVED10[8], DMACHTDR, DMACHRDR, DMACHTBAR,
  5694. DMACHRBAR;
  5695. };
  5696. #undef ETH
  5697. #define ETH ((struct stm32_eth *) (uintptr_t) 0x40028000)
  5698. #undef BIT
  5699. #define BIT(x) ((uint32_t) 1 << (x))
  5700. #define ETH_PKT_SIZE 1540 // Max frame size
  5701. #define ETH_DESC_CNT 4 // Descriptors count
  5702. #define ETH_DS 4 // Descriptor size (words)
  5703. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
  5704. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
  5705. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
  5706. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
  5707. static uint8_t s_txno; // Current TX descriptor
  5708. static uint8_t s_rxno; // Current RX descriptor
  5709. static struct mg_tcpip_if *s_ifp; // MIP interface
  5710. enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1, PHY_CSCR = 31 };
  5711. static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
  5712. ETH->MACMIIAR &= (7 << 2);
  5713. ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6);
  5714. ETH->MACMIIAR |= BIT(0);
  5715. while (ETH->MACMIIAR & BIT(0)) (void) 0;
  5716. return ETH->MACMIIDR;
  5717. }
  5718. static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
  5719. ETH->MACMIIDR = val;
  5720. ETH->MACMIIAR &= (7 << 2);
  5721. ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | BIT(1);
  5722. ETH->MACMIIAR |= BIT(0);
  5723. while (ETH->MACMIIAR & BIT(0)) (void) 0;
  5724. }
  5725. static uint32_t get_hclk(void) {
  5726. struct rcc {
  5727. volatile uint32_t CR, PLLCFGR, CFGR;
  5728. } *rcc = (struct rcc *) 0x40023800;
  5729. uint32_t clk = 0, hsi = 16000000 /* 16 MHz */, hse = 8000000 /* 8MHz */;
  5730. if (rcc->CFGR & (1 << 2)) {
  5731. clk = hse;
  5732. } else if (rcc->CFGR & (1 << 3)) {
  5733. uint32_t vco, m, n, p;
  5734. m = (rcc->PLLCFGR & (0x3f << 0)) >> 0;
  5735. n = (rcc->PLLCFGR & (0x1ff << 6)) >> 6;
  5736. p = (((rcc->PLLCFGR & (3 << 16)) >> 16) + 1) * 2;
  5737. clk = (rcc->PLLCFGR & (1 << 22)) ? hse : hsi;
  5738. vco = (uint32_t) ((uint64_t) clk * n / m);
  5739. clk = vco / p;
  5740. } else {
  5741. clk = hsi;
  5742. }
  5743. uint32_t hpre = (rcc->CFGR & (15 << 4)) >> 4;
  5744. if (hpre < 8) return clk;
  5745. uint8_t ahbptab[8] = {1, 2, 3, 4, 6, 7, 8, 9}; // log2(div)
  5746. return ((uint32_t) clk) >> ahbptab[hpre - 8];
  5747. }
  5748. // Guess CR from HCLK. MDC clock is generated from HCLK (AHB); as per 802.3,
  5749. // it must not exceed 2.5MHz As the AHB clock can be (and usually is) derived
  5750. // from the HSI (internal RC), and it can go above specs, the datasheets
  5751. // specify a range of frequencies and activate one of a series of dividers to
  5752. // keep the MDC clock safely below 2.5MHz. We guess a divider setting based on
  5753. // HCLK with a +5% drift. If the user uses a different clock from our
  5754. // defaults, needs to set the macros on top Valid for STM32F74xxx/75xxx
  5755. // (38.8.1) and STM32F42xxx/43xxx (33.8.1) (both 4.5% worst case drift)
  5756. static int guess_mdc_cr(void) {
  5757. uint8_t crs[] = {2, 3, 0, 1, 4, 5}; // ETH->MACMIIAR::CR values
  5758. uint8_t div[] = {16, 26, 42, 62, 102, 124}; // Respective HCLK dividers
  5759. uint32_t hclk = get_hclk(); // Guess system HCLK
  5760. int result = -1; // Invalid CR value
  5761. if (hclk < 25000000) {
  5762. MG_ERROR(("HCLK too low"));
  5763. } else {
  5764. for (int i = 0; i < 6; i++) {
  5765. if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
  5766. result = crs[i];
  5767. break;
  5768. }
  5769. }
  5770. if (result < 0) MG_ERROR(("HCLK too high"));
  5771. }
  5772. MG_DEBUG(("HCLK: %u, CR: %d", hclk, result));
  5773. return result;
  5774. }
  5775. static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
  5776. struct mg_tcpip_driver_stm32_data *d =
  5777. (struct mg_tcpip_driver_stm32_data *) ifp->driver_data;
  5778. s_ifp = ifp;
  5779. // Init RX descriptors
  5780. for (int i = 0; i < ETH_DESC_CNT; i++) {
  5781. s_rxdesc[i][0] = BIT(31); // Own
  5782. s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | BIT(14); // 2nd address chained
  5783. s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
  5784. s_rxdesc[i][3] =
  5785. (uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  5786. }
  5787. // Init TX descriptors
  5788. for (int i = 0; i < ETH_DESC_CNT; i++) {
  5789. s_txdesc[i][2] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
  5790. s_txdesc[i][3] =
  5791. (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  5792. }
  5793. ETH->DMABMR |= BIT(0); // Software reset
  5794. while ((ETH->DMABMR & BIT(0)) != 0) (void) 0; // Wait until done
  5795. // Set MDC clock divider. If user told us the value, use it. Otherwise, guess
  5796. int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
  5797. ETH->MACMIIAR = ((uint32_t) cr & 7) << 2;
  5798. // NOTE(cpq): we do not use extended descriptor bit 7, and do not use
  5799. // hardware checksum. Therefore, descriptor size is 4, not 8
  5800. // ETH->DMABMR = BIT(13) | BIT(16) | BIT(22) | BIT(23) | BIT(25);
  5801. ETH->MACIMR = BIT(3) | BIT(9); // Mask timestamp & PMT IT
  5802. ETH->MACFCR = BIT(7); // Disable zero quarta pause
  5803. // ETH->MACFFR = BIT(31); // Receive all
  5804. eth_write_phy(PHY_ADDR, PHY_BCR, BIT(15)); // Reset PHY
  5805. eth_write_phy(PHY_ADDR, PHY_BCR, BIT(12)); // Set autonegotiation
  5806. ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
  5807. ETH->DMATDLAR = (uint32_t) (uintptr_t) s_txdesc; // RX descriptors
  5808. ETH->DMAIER = BIT(6) | BIT(16); // RIE, NISE
  5809. ETH->MACCR = BIT(2) | BIT(3) | BIT(11) | BIT(14); // RE, TE, Duplex, Fast
  5810. ETH->DMAOMR = BIT(1) | BIT(13) | BIT(21) | BIT(25); // SR, ST, TSF, RSF
  5811. // MAC address filtering
  5812. ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
  5813. ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
  5814. ((uint32_t) ifp->mac[2] << 16) |
  5815. ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
  5816. return true;
  5817. }
  5818. static size_t mg_tcpip_driver_stm32_tx(const void *buf, size_t len,
  5819. struct mg_tcpip_if *ifp) {
  5820. if (len > sizeof(s_txbuf[s_txno])) {
  5821. MG_ERROR(("Frame too big, %ld", (long) len));
  5822. len = 0; // Frame is too big
  5823. } else if ((s_txdesc[s_txno][0] & BIT(31))) {
  5824. ifp->nerr++;
  5825. MG_ERROR(("No free descriptors"));
  5826. // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) ETH->DMASR);
  5827. len = 0; // All descriptors are busy, fail
  5828. } else {
  5829. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  5830. s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
  5831. s_txdesc[s_txno][0] = BIT(20) | BIT(28) | BIT(29) | BIT(30); // Chain,FS,LS
  5832. s_txdesc[s_txno][0] |= BIT(31); // Set OWN bit - let DMA take over
  5833. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  5834. }
  5835. ETH->DMASR = BIT(2) | BIT(5); // Clear any prior TBUS/TUS
  5836. ETH->DMATPDR = 0; // and resume
  5837. return len;
  5838. }
  5839. static bool mg_tcpip_driver_stm32_up(struct mg_tcpip_if *ifp) {
  5840. uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
  5841. bool up = bsr & BIT(2) ? 1 : 0;
  5842. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  5843. uint32_t scsr = eth_read_phy(PHY_ADDR, PHY_CSCR);
  5844. uint32_t maccr = ETH->MACCR | BIT(14) | BIT(11); // 100M, Full-duplex
  5845. if ((scsr & BIT(3)) == 0) maccr &= ~BIT(14); // 10M
  5846. if ((scsr & BIT(4)) == 0) maccr &= ~BIT(11); // Half-duplex
  5847. ETH->MACCR = maccr; // IRQ handler does not fiddle with this register
  5848. MG_DEBUG(("Link is %uM %s-duplex", maccr & BIT(14) ? 100 : 10,
  5849. maccr & BIT(11) ? "full" : "half"));
  5850. }
  5851. return up;
  5852. }
  5853. void ETH_IRQHandler(void);
  5854. void ETH_IRQHandler(void) {
  5855. if (ETH->DMASR & BIT(6)) { // Frame received, loop
  5856. ETH->DMASR = BIT(16) | BIT(6); // Clear flag
  5857. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  5858. if (s_rxdesc[s_rxno][0] & BIT(31)) break; // exit when done
  5859. if (((s_rxdesc[s_rxno][0] & (BIT(8) | BIT(9))) == (BIT(8) | BIT(9))) &&
  5860. !(s_rxdesc[s_rxno][0] & BIT(15))) { // skip partial/errored frames
  5861. uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
  5862. // printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
  5863. // ETH->DMASR);
  5864. mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
  5865. }
  5866. s_rxdesc[s_rxno][0] = BIT(31);
  5867. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  5868. }
  5869. }
  5870. ETH->DMASR = BIT(7); // Clear possible RBUS while processing
  5871. ETH->DMARPDR = 0; // and resume RX
  5872. }
  5873. struct mg_tcpip_driver mg_tcpip_driver_stm32 = {mg_tcpip_driver_stm32_init,
  5874. mg_tcpip_driver_stm32_tx, NULL,
  5875. mg_tcpip_driver_stm32_up};
  5876. #endif
  5877. #ifdef MG_ENABLE_LINES
  5878. #line 1 "src/tcpip/driver_stm32h.c"
  5879. #endif
  5880. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
  5881. MG_ENABLE_DRIVER_STM32H
  5882. struct stm32h_eth {
  5883. volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
  5884. RESERVED1[14], MACVTR, RESERVED2, MACVHTR, RESERVED3, MACVIR, MACIVIR,
  5885. RESERVED4[2], MACTFCR, RESERVED5[7], MACRFCR, RESERVED6[7], MACISR,
  5886. MACIER, MACRXTXSR, RESERVED7, MACPCSR, MACRWKPFR, RESERVED8[2], MACLCSR,
  5887. MACLTCR, MACLETR, MAC1USTCR, RESERVED9[12], MACVR, MACDR, RESERVED10,
  5888. MACHWF0R, MACHWF1R, MACHWF2R, RESERVED11[54], MACMDIOAR, MACMDIODR,
  5889. RESERVED12[2], MACARPAR, RESERVED13[59], MACA0HR, MACA0LR, MACA1HR,
  5890. MACA1LR, MACA2HR, MACA2LR, MACA3HR, MACA3LR, RESERVED14[248], MMCCR,
  5891. MMCRIR, MMCTIR, MMCRIMR, MMCTIMR, RESERVED15[14], MMCTSCGPR, MMCTMCGPR,
  5892. RESERVED16[5], MMCTPCGR, RESERVED17[10], MMCRCRCEPR, MMCRAEPR,
  5893. RESERVED18[10], MMCRUPGR, RESERVED19[9], MMCTLPIMSTR, MMCTLPITCR,
  5894. MMCRLPIMSTR, MMCRLPITCR, RESERVED20[65], MACL3L4C0R, MACL4A0R,
  5895. RESERVED21[2], MACL3A0R0R, MACL3A1R0R, MACL3A2R0R, MACL3A3R0R,
  5896. RESERVED22[4], MACL3L4C1R, MACL4A1R, RESERVED23[2], MACL3A0R1R,
  5897. MACL3A1R1R, MACL3A2R1R, MACL3A3R1R, RESERVED24[108], MACTSCR, MACSSIR,
  5898. MACSTSR, MACSTNR, MACSTSUR, MACSTNUR, MACTSAR, RESERVED25, MACTSSR,
  5899. RESERVED26[3], MACTTSSNR, MACTTSSSR, RESERVED27[2], MACACR, RESERVED28,
  5900. MACATSNR, MACATSSR, MACTSIACR, MACTSEACR, MACTSICNR, MACTSECNR,
  5901. RESERVED29[4], MACPPSCR, RESERVED30[3], MACPPSTTSR, MACPPSTTNR, MACPPSIR,
  5902. MACPPSWR, RESERVED31[12], MACPOCR, MACSPI0R, MACSPI1R, MACSPI2R, MACLMIR,
  5903. RESERVED32[11], MTLOMR, RESERVED33[7], MTLISR, RESERVED34[55], MTLTQOMR,
  5904. MTLTQUR, MTLTQDR, RESERVED35[8], MTLQICSR, MTLRQOMR, MTLRQMPOCR, MTLRQDR,
  5905. RESERVED36[177], DMAMR, DMASBMR, DMAISR, DMADSR, RESERVED37[60], DMACCR,
  5906. DMACTCR, DMACRCR, RESERVED38[2], DMACTDLAR, RESERVED39, DMACRDLAR,
  5907. DMACTDTPR, RESERVED40, DMACRDTPR, DMACTDRLR, DMACRDRLR, DMACIER,
  5908. DMACRIWTR, DMACSFCSR, RESERVED41, DMACCATDR, RESERVED42, DMACCARDR,
  5909. RESERVED43, DMACCATBR, RESERVED44, DMACCARBR, DMACSR, RESERVED45[2],
  5910. DMACMFCR;
  5911. };
  5912. #undef ETH
  5913. #define ETH \
  5914. ((struct stm32h_eth *) (uintptr_t) (0x40000000UL + 0x00020000UL + 0x8000UL))
  5915. #undef BIT
  5916. #define BIT(x) ((uint32_t) 1 << (x))
  5917. #define ETH_PKT_SIZE 1540 // Max frame size
  5918. #define ETH_DESC_CNT 4 // Descriptors count
  5919. #define ETH_DS 4 // Descriptor size (words)
  5920. static volatile uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
  5921. static volatile uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
  5922. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
  5923. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
  5924. static struct mg_tcpip_if *s_ifp; // MIP interface
  5925. enum {
  5926. PHY_ADDR = 0,
  5927. PHY_BCR = 0,
  5928. PHY_BSR = 1,
  5929. PHY_CSCR = 31
  5930. }; // PHY constants
  5931. static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
  5932. ETH->MACMDIOAR &= (0xF << 8);
  5933. ETH->MACMDIOAR |= ((uint32_t) addr << 21) | ((uint32_t) reg << 16) | 3 << 2;
  5934. ETH->MACMDIOAR |= BIT(0);
  5935. while (ETH->MACMDIOAR & BIT(0)) (void) 0;
  5936. return ETH->MACMDIODR;
  5937. }
  5938. static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
  5939. ETH->MACMDIODR = val;
  5940. ETH->MACMDIOAR &= (0xF << 8);
  5941. ETH->MACMDIOAR |= ((uint32_t) addr << 21) | ((uint32_t) reg << 16) | 1 << 2;
  5942. ETH->MACMDIOAR |= BIT(0);
  5943. while (ETH->MACMDIOAR & BIT(0)) (void) 0;
  5944. }
  5945. static uint32_t get_hclk(void) {
  5946. struct rcc {
  5947. volatile uint32_t CR, HSICFGR, CRRCR, CSICFGR, CFGR, RESERVED1, D1CFGR,
  5948. D2CFGR, D3CFGR, RESERVED2, PLLCKSELR, PLLCFGR, PLL1DIVR, PLL1FRACR,
  5949. PLL2DIVR, PLL2FRACR, PLL3DIVR, PLL3FRACR, RESERVED3, D1CCIPR, D2CCIP1R,
  5950. D2CCIP2R, D3CCIPR, RESERVED4, CIER, CIFR, CICR, RESERVED5, BDCR, CSR,
  5951. RESERVED6, AHB3RSTR, AHB1RSTR, AHB2RSTR, AHB4RSTR, APB3RSTR, APB1LRSTR,
  5952. APB1HRSTR, APB2RSTR, APB4RSTR, GCR, RESERVED8, D3AMR, RESERVED11[9],
  5953. RSR, AHB3ENR, AHB1ENR, AHB2ENR, AHB4ENR, APB3ENR, APB1LENR, APB1HENR,
  5954. APB2ENR, APB4ENR, RESERVED12, AHB3LPENR, AHB1LPENR, AHB2LPENR,
  5955. AHB4LPENR, APB3LPENR, APB1LLPENR, APB1HLPENR, APB2LPENR, APB4LPENR,
  5956. RESERVED13[4];
  5957. } *rcc = ((struct rcc *) (0x40000000 + 0x18020000 + 0x4400));
  5958. uint32_t clk = 0, hsi = 64000000 /* 64 MHz */, hse = 8000000 /* 8MHz */,
  5959. csi = 4000000 /* 4MHz */;
  5960. unsigned int sel = (rcc->CFGR & (7 << 3)) >> 3;
  5961. if (sel == 1) {
  5962. clk = csi;
  5963. } else if (sel == 2) {
  5964. clk = hse;
  5965. } else if (sel == 3) {
  5966. uint32_t vco, m, n, p;
  5967. unsigned int src = (rcc->PLLCKSELR & (3 << 0)) >> 0;
  5968. m = ((rcc->PLLCKSELR & (0x3F << 4)) >> 4);
  5969. n = ((rcc->PLL1DIVR & (0x1FF << 0)) >> 0) + 1 +
  5970. ((rcc->PLLCFGR & BIT(0)) ? 1 : 0); // round-up in fractional mode
  5971. p = ((rcc->PLL1DIVR & (0x7F << 9)) >> 9) + 1;
  5972. if (src == 1) {
  5973. clk = csi;
  5974. } else if (src == 2) {
  5975. clk = hse;
  5976. } else {
  5977. clk = hsi;
  5978. clk >>= ((rcc->CR & 3) >> 3);
  5979. }
  5980. vco = (uint32_t) ((uint64_t) clk * n / m);
  5981. clk = vco / p;
  5982. } else {
  5983. clk = hsi;
  5984. clk >>= ((rcc->CR & 3) >> 3);
  5985. }
  5986. const uint8_t cptab[12] = {1, 2, 3, 4, 6, 7, 8, 9}; // log2(div)
  5987. uint32_t d1cpre = (rcc->D1CFGR & (0x0F << 8)) >> 8;
  5988. if (d1cpre >= 8) clk >>= cptab[d1cpre - 8];
  5989. MG_DEBUG(("D1 CLK: %u", clk));
  5990. uint32_t hpre = (rcc->D1CFGR & (0x0F << 0)) >> 0;
  5991. if (hpre < 8) return clk;
  5992. return ((uint32_t) clk) >> cptab[hpre - 8];
  5993. }
  5994. // Guess CR from AHB1 clock. MDC clock is generated from the ETH peripheral
  5995. // clock (AHB1); as per 802.3, it must not exceed 2. As the AHB clock can
  5996. // be derived from HSI or CSI (internal RC) clocks, and those can go above
  5997. // specs, the datasheets specify a range of frequencies and activate one of a
  5998. // series of dividers to keep the MDC clock safely below 2.5MHz. We guess a
  5999. // divider setting based on HCLK with some drift. If the user uses a different
  6000. // clock from our defaults, needs to set the macros on top. Valid for
  6001. // STM32H74xxx/75xxx (58.11.4)(4.5% worst case drift)(CSI clock has a 7.5 %
  6002. // worst case drift @ max temp)
  6003. static int guess_mdc_cr(void) {
  6004. const uint8_t crs[] = {2, 3, 0, 1, 4, 5}; // ETH->MACMDIOAR::CR values
  6005. const uint8_t div[] = {16, 26, 42, 62, 102, 124}; // Respective HCLK dividers
  6006. uint32_t hclk = get_hclk(); // Guess system HCLK
  6007. int result = -1; // Invalid CR value
  6008. for (int i = 0; i < 6; i++) {
  6009. if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
  6010. result = crs[i];
  6011. break;
  6012. }
  6013. }
  6014. if (result < 0) MG_ERROR(("HCLK too high"));
  6015. MG_DEBUG(("HCLK: %u, CR: %d", hclk, result));
  6016. return result;
  6017. }
  6018. static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
  6019. struct mg_tcpip_driver_stm32h_data *d =
  6020. (struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
  6021. s_ifp = ifp;
  6022. // Init RX descriptors
  6023. for (int i = 0; i < ETH_DESC_CNT; i++) {
  6024. s_rxdesc[i][0] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
  6025. s_rxdesc[i][3] = BIT(31) | BIT(30) | BIT(24); // OWN, IOC, BUF1V
  6026. }
  6027. // Init TX descriptors
  6028. for (int i = 0; i < ETH_DESC_CNT; i++) {
  6029. s_txdesc[i][0] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
  6030. }
  6031. ETH->DMAMR |= BIT(0); // Software reset
  6032. while ((ETH->DMAMR & BIT(0)) != 0) (void) 0; // Wait until done
  6033. // Set MDC clock divider. If user told us the value, use it. Otherwise, guess
  6034. int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
  6035. ETH->MACMDIOAR = ((uint32_t) cr & 0xF) << 8;
  6036. // NOTE(scaprile): We do not use timing facilities so the DMA engine does not
  6037. // re-write buffer address
  6038. ETH->DMAMR = 0 << 16; // use interrupt mode 0 (58.8.1) (reset value)
  6039. ETH->DMASBMR |= BIT(12); // AAL NOTE(scaprile): is this actually needed
  6040. ETH->MACIER = 0; // Do not enable additional irq sources (reset value)
  6041. ETH->MACTFCR = BIT(7); // Disable zero-quanta pause
  6042. // ETH->MACPFR = BIT(31); // Receive all
  6043. eth_write_phy(PHY_ADDR, PHY_BCR, BIT(15)); // Reset PHY
  6044. eth_write_phy(PHY_ADDR, PHY_BCR, BIT(12)); // Set autonegotiation
  6045. ETH->DMACRDLAR =
  6046. (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors start address
  6047. ETH->DMACRDRLR = ETH_DESC_CNT - 1; // ring length
  6048. ETH->DMACRDTPR =
  6049. (uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT -
  6050. 1]; // last valid descriptor address
  6051. ETH->DMACTDLAR =
  6052. (uint32_t) (uintptr_t) s_txdesc; // TX descriptors start address
  6053. ETH->DMACTDRLR = ETH_DESC_CNT - 1; // ring length
  6054. ETH->DMACTDTPR =
  6055. (uint32_t) (uintptr_t) s_txdesc; // first available descriptor address
  6056. ETH->DMACCR = 0; // DSL = 0 (contiguous descriptor table) (reset value)
  6057. ETH->DMACIER = BIT(6) | BIT(15); // RIE, NIE
  6058. ETH->MACCR = BIT(0) | BIT(1) | BIT(13) | BIT(14) |
  6059. BIT(15); // RE, TE, Duplex, Fast, Reserved
  6060. ETH->MTLTQOMR |= BIT(1); // TSF
  6061. ETH->MTLRQOMR |= BIT(5); // RSF
  6062. ETH->DMACTCR |= BIT(0); // ST
  6063. ETH->DMACRCR |= BIT(0); // SR
  6064. // MAC address filtering
  6065. ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
  6066. ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
  6067. ((uint32_t) ifp->mac[2] << 16) |
  6068. ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
  6069. return true;
  6070. }
  6071. static uint32_t s_txno;
  6072. static size_t mg_tcpip_driver_stm32h_tx(const void *buf, size_t len,
  6073. struct mg_tcpip_if *ifp) {
  6074. if (len > sizeof(s_txbuf[s_txno])) {
  6075. MG_ERROR(("Frame too big, %ld", (long) len));
  6076. len = 0; // Frame is too big
  6077. } else if ((s_txdesc[s_txno][3] & BIT(31))) {
  6078. MG_ERROR(("No free descriptors: %u %08X %08X %08X", s_txno,
  6079. s_txdesc[s_txno][3], ETH->DMACSR, ETH->DMACTCR));
  6080. for (int i = 0; i < ETH_DESC_CNT; i++) MG_ERROR(("%08X", s_txdesc[i][3]));
  6081. len = 0; // All descriptors are busy, fail
  6082. } else {
  6083. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  6084. s_txdesc[s_txno][2] = (uint32_t) len; // Set data len
  6085. s_txdesc[s_txno][3] = BIT(28) | BIT(29); // FD, LD
  6086. s_txdesc[s_txno][3] |= BIT(31); // Set OWN bit - let DMA take over
  6087. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  6088. }
  6089. ETH->DMACSR |= BIT(2) | BIT(1); // Clear any prior TBU, TPS
  6090. ETH->DMACTDTPR = (uint32_t) (uintptr_t) &s_txdesc[s_txno]; // and resume
  6091. return len;
  6092. (void) ifp;
  6093. }
  6094. static bool mg_tcpip_driver_stm32h_up(struct mg_tcpip_if *ifp) {
  6095. uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
  6096. bool up = bsr & BIT(2) ? 1 : 0;
  6097. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  6098. uint32_t scsr = eth_read_phy(PHY_ADDR, PHY_CSCR);
  6099. uint32_t maccr = ETH->MACCR | BIT(14) | BIT(13); // 100M, Full-duplex
  6100. if ((scsr & BIT(3)) == 0) maccr &= ~BIT(14); // 10M
  6101. if ((scsr & BIT(4)) == 0) maccr &= ~BIT(13); // Half-duplex
  6102. ETH->MACCR = maccr; // IRQ handler does not fiddle with this register
  6103. MG_DEBUG(("Link is %uM %s-duplex", maccr & BIT(14) ? 100 : 10,
  6104. maccr & BIT(13) ? "full" : "half"));
  6105. }
  6106. return up;
  6107. }
  6108. void ETH_IRQHandler(void);
  6109. static uint32_t s_rxno;
  6110. void ETH_IRQHandler(void) {
  6111. if (ETH->DMACSR & BIT(6)) { // Frame received, loop
  6112. ETH->DMACSR = BIT(15) | BIT(6); // Clear flag
  6113. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  6114. if (s_rxdesc[s_rxno][3] & BIT(31)) break; // exit when done
  6115. if (((s_rxdesc[s_rxno][3] & (BIT(28) | BIT(29))) ==
  6116. (BIT(28) | BIT(29))) &&
  6117. !(s_rxdesc[s_rxno][3] & BIT(15))) { // skip partial/errored frames
  6118. uint32_t len = s_rxdesc[s_rxno][3] & (BIT(15) - 1);
  6119. // MG_DEBUG(("%lx %lu %lx %08lx", s_rxno, len, s_rxdesc[s_rxno][3],
  6120. // ETH->DMACSR));
  6121. mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
  6122. }
  6123. s_rxdesc[s_rxno][3] = BIT(31) | BIT(30) | BIT(24); // OWN, IOC, BUF1V
  6124. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  6125. }
  6126. }
  6127. ETH->DMACSR = BIT(7) | BIT(8); // Clear possible RBU RPS while processing
  6128. ETH->DMACRDTPR =
  6129. (uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT - 1]; // and resume RX
  6130. }
  6131. struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
  6132. mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, NULL,
  6133. mg_tcpip_driver_stm32h_up};
  6134. #endif
  6135. #ifdef MG_ENABLE_LINES
  6136. #line 1 "src/tcpip/driver_tm4c.c"
  6137. #endif
  6138. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
  6139. struct tm4c_emac {
  6140. volatile uint32_t EMACCFG, EMACFRAMEFLTR, EMACHASHTBLH, EMACHASHTBLL,
  6141. EMACMIIADDR, EMACMIIDATA, EMACFLOWCTL, EMACVLANTG, RESERVED0, EMACSTATUS,
  6142. EMACRWUFF, EMACPMTCTLSTAT, RESERVED1[2], EMACRIS, EMACIM, EMACADDR0H,
  6143. EMACADDR0L, EMACADDR1H, EMACADDR1L, EMACADDR2H, EMACADDR2L, EMACADDR3H,
  6144. EMACADDR3L, RESERVED2[31], EMACWDOGTO, RESERVED3[8], EMACMMCCTRL,
  6145. EMACMMCRXRIS, EMACMMCTXRIS, EMACMMCRXIM, EMACMMCTXIM, RESERVED4,
  6146. EMACTXCNTGB, RESERVED5[12], EMACTXCNTSCOL, EMACTXCNTMCOL, RESERVED6[4],
  6147. EMACTXOCTCNTG, RESERVED7[6], EMACRXCNTGB, RESERVED8[4], EMACRXCNTCRCERR,
  6148. EMACRXCNTALGNERR, RESERVED9[10], EMACRXCNTGUNI, RESERVED10[239],
  6149. EMACVLNINCREP, EMACVLANHASH, RESERVED11[93], EMACTIMSTCTRL, EMACSUBSECINC,
  6150. EMACTIMSEC, EMACTIMNANO, EMACTIMSECU, EMACTIMNANOU, EMACTIMADD,
  6151. EMACTARGSEC, EMACTARGNANO, EMACHWORDSEC, EMACTIMSTAT, EMACPPSCTRL,
  6152. RESERVED12[12], EMACPPS0INTVL, EMACPPS0WIDTH, RESERVED13[294],
  6153. EMACDMABUSMOD, EMACTXPOLLD, EMACRXPOLLD, EMACRXDLADDR, EMACTXDLADDR,
  6154. EMACDMARIS, EMACDMAOPMODE, EMACDMAIM, EMACMFBOC, EMACRXINTWDT,
  6155. RESERVED14[8], EMACHOSTXDESC, EMACHOSRXDESC, EMACHOSTXBA, EMACHOSRXBA,
  6156. RESERVED15[218], EMACPP, EMACPC, EMACCC, RESERVED16, EMACEPHYRIS,
  6157. EMACEPHYIM, EMACEPHYIMSC;
  6158. };
  6159. #undef EMAC
  6160. #define EMAC ((struct tm4c_emac *) (uintptr_t) 0x400EC000)
  6161. #undef BIT
  6162. #define BIT(x) ((uint32_t) 1 << (x))
  6163. #define ETH_PKT_SIZE 1540 // Max frame size
  6164. #define ETH_DESC_CNT 4 // Descriptors count
  6165. #define ETH_DS 4 // Descriptor size (words)
  6166. static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
  6167. static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
  6168. static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
  6169. static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
  6170. static struct mg_tcpip_if *s_ifp; // MIP interface
  6171. enum {
  6172. EPHY_ADDR = 0,
  6173. EPHYBMCR = 0,
  6174. EPHYBMSR = 1,
  6175. EPHYSTS = 16
  6176. }; // PHY constants
  6177. static inline void tm4cspin(volatile uint32_t count) {
  6178. while (count--) (void) 0;
  6179. }
  6180. static uint32_t emac_read_phy(uint8_t addr, uint8_t reg) {
  6181. EMAC->EMACMIIADDR &= (0xf << 2);
  6182. EMAC->EMACMIIADDR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6);
  6183. EMAC->EMACMIIADDR |= BIT(0);
  6184. while (EMAC->EMACMIIADDR & BIT(0)) tm4cspin(1);
  6185. return EMAC->EMACMIIDATA;
  6186. }
  6187. static void emac_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
  6188. EMAC->EMACMIIDATA = val;
  6189. EMAC->EMACMIIADDR &= (0xf << 2);
  6190. EMAC->EMACMIIADDR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | BIT(1);
  6191. EMAC->EMACMIIADDR |= BIT(0);
  6192. while (EMAC->EMACMIIADDR & BIT(0)) tm4cspin(1);
  6193. }
  6194. static uint32_t get_sysclk(void) {
  6195. struct sysctl {
  6196. volatile uint32_t DONTCARE0[44], RSCLKCFG, DONTCARE1[43], PLLFREQ0,
  6197. PLLFREQ1;
  6198. } *sysctl = (struct sysctl *) 0x400FE000;
  6199. uint32_t clk = 0, piosc = 16000000 /* 16 MHz */, mosc = 25000000 /* 25MHz */;
  6200. if (sysctl->RSCLKCFG & (1 << 28)) { // USEPLL
  6201. uint32_t fin, vco, mdiv, n, q, psysdiv;
  6202. uint32_t pllsrc = (sysctl->RSCLKCFG & (0xf << 24)) >> 24;
  6203. if (pllsrc == 0) {
  6204. clk = piosc;
  6205. } else if (pllsrc == 3) {
  6206. clk = mosc;
  6207. } else {
  6208. MG_ERROR(("Unsupported clock source"));
  6209. }
  6210. q = (sysctl->PLLFREQ1 & (0x1f << 8)) >> 8;
  6211. n = (sysctl->PLLFREQ1 & (0x1f << 0)) >> 0;
  6212. fin = clk / ((q + 1) * (n + 1));
  6213. mdiv = (sysctl->PLLFREQ0 & (0x3ff << 0)) >>
  6214. 0; // mint + (mfrac / 1024); MFRAC not supported
  6215. psysdiv = (sysctl->RSCLKCFG & (0x3f << 0)) >> 0;
  6216. vco = (uint32_t) ((uint64_t) fin * mdiv);
  6217. return vco / (psysdiv + 1);
  6218. }
  6219. uint32_t oscsrc = (sysctl->RSCLKCFG & (0xf << 20)) >> 20;
  6220. if (oscsrc == 0) {
  6221. clk = piosc;
  6222. } else if (oscsrc == 3) {
  6223. clk = mosc;
  6224. } else {
  6225. MG_ERROR(("Unsupported clock source"));
  6226. }
  6227. uint32_t osysdiv = (sysctl->RSCLKCFG & (0xf << 16)) >> 16;
  6228. return clk / (osysdiv + 1);
  6229. }
  6230. // Guess CR from SYSCLK. MDC clock is generated from SYSCLK (AHB); as per
  6231. // 802.3, it must not exceed 2.5MHz (also 20.4.2.6) As the AHB clock can be
  6232. // derived from the PIOSC (internal RC), and it can go above specs, the
  6233. // datasheets specify a range of frequencies and activate one of a series of
  6234. // dividers to keep the MDC clock safely below 2.5MHz. We guess a divider
  6235. // setting based on SYSCLK with a +5% drift. If the user uses a different clock
  6236. // from our defaults, needs to set the macros on top Valid for TM4C129x (20.7)
  6237. // (4.5% worst case drift)
  6238. // The PHY receives the main oscillator (MOSC) (20.3.1)
  6239. static int guess_mdc_cr(void) {
  6240. uint8_t crs[] = {2, 3, 0, 1}; // EMAC->MACMIIAR::CR values
  6241. uint8_t div[] = {16, 26, 42, 62}; // Respective HCLK dividers
  6242. uint32_t sysclk = get_sysclk(); // Guess system SYSCLK
  6243. int result = -1; // Invalid CR value
  6244. if (sysclk < 25000000) {
  6245. MG_ERROR(("SYSCLK too low"));
  6246. } else {
  6247. for (int i = 0; i < 4; i++) {
  6248. if (sysclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
  6249. result = crs[i];
  6250. break;
  6251. }
  6252. }
  6253. if (result < 0) MG_ERROR(("SYSCLK too high"));
  6254. }
  6255. MG_DEBUG(("SYSCLK: %u, CR: %d", sysclk, result));
  6256. return result;
  6257. }
  6258. static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
  6259. struct mg_tcpip_driver_tm4c_data *d =
  6260. (struct mg_tcpip_driver_tm4c_data *) ifp->driver_data;
  6261. s_ifp = ifp;
  6262. // Init RX descriptors
  6263. for (int i = 0; i < ETH_DESC_CNT; i++) {
  6264. s_rxdesc[i][0] = BIT(31); // Own
  6265. s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | BIT(14); // 2nd address chained
  6266. s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
  6267. s_rxdesc[i][3] =
  6268. (uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  6269. // MG_DEBUG(("%d %p", i, s_rxdesc[i]));
  6270. }
  6271. // Init TX descriptors
  6272. for (int i = 0; i < ETH_DESC_CNT; i++) {
  6273. s_txdesc[i][2] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
  6274. s_txdesc[i][3] =
  6275. (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain
  6276. }
  6277. EMAC->EMACDMABUSMOD |= BIT(0); // Software reset
  6278. while ((EMAC->EMACDMABUSMOD & BIT(0)) != 0) tm4cspin(1); // Wait until done
  6279. // Set MDC clock divider. If user told us the value, use it. Otherwise, guess
  6280. int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
  6281. EMAC->EMACMIIADDR = ((uint32_t) cr & 0xf) << 2;
  6282. // NOTE(cpq): we do not use extended descriptor bit 7, and do not use
  6283. // hardware checksum. Therefore, descriptor size is 4, not 8
  6284. // EMAC->EMACDMABUSMOD = BIT(13) | BIT(16) | BIT(22) | BIT(23) | BIT(25);
  6285. EMAC->EMACIM = BIT(3) | BIT(9); // Mask timestamp & PMT IT
  6286. EMAC->EMACFLOWCTL = BIT(7); // Disable zero-quanta pause
  6287. // EMAC->EMACFRAMEFLTR = BIT(31); // Receive all
  6288. // EMAC->EMACPC defaults to internal PHY (EPHY) in MMI mode
  6289. emac_write_phy(EPHY_ADDR, EPHYBMCR, BIT(15)); // Reset internal PHY (EPHY)
  6290. emac_write_phy(EPHY_ADDR, EPHYBMCR, BIT(12)); // Set autonegotiation
  6291. EMAC->EMACRXDLADDR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
  6292. EMAC->EMACTXDLADDR = (uint32_t) (uintptr_t) s_txdesc; // TX descriptors
  6293. EMAC->EMACDMAIM = BIT(6) | BIT(16); // RIE, NIE
  6294. EMAC->EMACCFG = BIT(2) | BIT(3) | BIT(11) | BIT(14); // RE, TE, Duplex, Fast
  6295. EMAC->EMACDMAOPMODE =
  6296. BIT(1) | BIT(13) | BIT(21) | BIT(25); // SR, ST, TSF, RSF
  6297. EMAC->EMACADDR0H = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
  6298. EMAC->EMACADDR0L = (uint32_t) (ifp->mac[3] << 24) |
  6299. ((uint32_t) ifp->mac[2] << 16) |
  6300. ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
  6301. // NOTE(scaprile) There are 3 additional slots for filtering, disabled by
  6302. // default. This also applies to the STM32 driver (at least for F7)
  6303. return true;
  6304. }
  6305. static uint32_t s_txno;
  6306. static size_t mg_tcpip_driver_tm4c_tx(const void *buf, size_t len,
  6307. struct mg_tcpip_if *ifp) {
  6308. if (len > sizeof(s_txbuf[s_txno])) {
  6309. MG_ERROR(("Frame too big, %ld", (long) len));
  6310. len = 0; // fail
  6311. } else if ((s_txdesc[s_txno][0] & BIT(31))) {
  6312. MG_ERROR(("No descriptors available"));
  6313. // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long)
  6314. // EMAC->EMACDMARIS);
  6315. len = 0; // fail
  6316. } else {
  6317. memcpy(s_txbuf[s_txno], buf, len); // Copy data
  6318. s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
  6319. s_txdesc[s_txno][0] =
  6320. BIT(20) | BIT(28) | BIT(29) | BIT(30); // Chain,FS,LS,IC
  6321. s_txdesc[s_txno][0] |= BIT(31); // Set OWN bit - let DMA take over
  6322. if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
  6323. }
  6324. EMAC->EMACDMARIS = BIT(2) | BIT(5); // Clear any prior TU/UNF
  6325. EMAC->EMACTXPOLLD = 0; // and resume
  6326. return len;
  6327. (void) ifp;
  6328. }
  6329. static bool mg_tcpip_driver_tm4c_up(struct mg_tcpip_if *ifp) {
  6330. uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
  6331. bool up = (bmsr & BIT(2)) ? 1 : 0;
  6332. if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
  6333. uint32_t sts = emac_read_phy(EPHY_ADDR, EPHYSTS);
  6334. uint32_t emaccfg = EMAC->EMACCFG | BIT(14) | BIT(11); // 100M, Full-duplex
  6335. if (sts & BIT(1)) emaccfg &= ~BIT(14); // 10M
  6336. if ((sts & BIT(2)) == 0) emaccfg &= ~BIT(11); // Half-duplex
  6337. EMAC->EMACCFG = emaccfg; // IRQ handler does not fiddle with this register
  6338. MG_DEBUG(("Link is %uM %s-duplex", emaccfg & BIT(14) ? 100 : 10,
  6339. emaccfg & BIT(11) ? "full" : "half"));
  6340. }
  6341. return up;
  6342. }
  6343. void EMAC0_IRQHandler(void);
  6344. static uint32_t s_rxno;
  6345. void EMAC0_IRQHandler(void) {
  6346. if (EMAC->EMACDMARIS & BIT(6)) { // Frame received, loop
  6347. EMAC->EMACDMARIS = BIT(16) | BIT(6); // Clear flag
  6348. for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
  6349. if (s_rxdesc[s_rxno][0] & BIT(31)) break; // exit when done
  6350. if (((s_rxdesc[s_rxno][0] & (BIT(8) | BIT(9))) == (BIT(8) | BIT(9))) &&
  6351. !(s_rxdesc[s_rxno][0] & BIT(15))) { // skip partial/errored frames
  6352. uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
  6353. // printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
  6354. // EMAC->EMACDMARIS);
  6355. mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
  6356. }
  6357. s_rxdesc[s_rxno][0] = BIT(31);
  6358. if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
  6359. }
  6360. }
  6361. EMAC->EMACDMARIS = BIT(7); // Clear possible RU while processing
  6362. EMAC->EMACRXPOLLD = 0; // and resume RX
  6363. }
  6364. struct mg_tcpip_driver mg_tcpip_driver_tm4c = {mg_tcpip_driver_tm4c_init,
  6365. mg_tcpip_driver_tm4c_tx, NULL,
  6366. mg_tcpip_driver_tm4c_up};
  6367. #endif
  6368. #ifdef MG_ENABLE_LINES
  6369. #line 1 "src/tcpip/driver_w5500.c"
  6370. #endif
  6371. #if MG_ENABLE_TCPIP
  6372. enum { W5500_CR = 0, W5500_S0 = 1, W5500_TX0 = 2, W5500_RX0 = 3 };
  6373. static void w5500_txn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, bool wr,
  6374. void *buf, size_t len) {
  6375. uint8_t *p = (uint8_t *) buf;
  6376. uint8_t cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255),
  6377. (uint8_t) ((block << 3) | (wr ? 4 : 0))};
  6378. s->begin(s->spi);
  6379. for (size_t i = 0; i < sizeof(cmd); i++) s->txn(s->spi, cmd[i]);
  6380. for (size_t i = 0; i < len; i++) {
  6381. uint8_t r = s->txn(s->spi, p[i]);
  6382. if (!wr) p[i] = r;
  6383. }
  6384. s->end(s->spi);
  6385. }
  6386. // clang-format off
  6387. static void w5500_wn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); }
  6388. static void w5500_w1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); }
  6389. static void w5500_w2(struct mg_tcpip_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)); }
  6390. static void w5500_rn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); }
  6391. static uint8_t w5500_r1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; }
  6392. static uint16_t w5500_r2(struct mg_tcpip_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]); }
  6393. // clang-format on
  6394. static size_t w5500_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
  6395. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  6396. uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2; // Read recv len
  6397. while ((n2 = w5500_r2(s, W5500_S0, 0x26)) > n) n = n2; // Until it is stable
  6398. // printf("RSR: %d\n", (int) n);
  6399. if (n > 0) {
  6400. uint16_t ptr = w5500_r2(s, W5500_S0, 0x28); // Get read pointer
  6401. n = w5500_r2(s, W5500_RX0, ptr); // Read frame length
  6402. if (n <= len + 2 && n > 1) {
  6403. r = (uint16_t) (n - 2);
  6404. w5500_rn(s, W5500_RX0, (uint16_t) (ptr + 2), buf, r);
  6405. }
  6406. w5500_w2(s, W5500_S0, 0x28, (uint16_t) (ptr + n)); // Advance read pointer
  6407. w5500_w1(s, W5500_S0, 1, 0x40); // Sock0 CR -> RECV
  6408. // printf(" RX_RD: tot=%u n=%u r=%u\n", n2, n, r);
  6409. }
  6410. return r;
  6411. }
  6412. static size_t w5500_tx(const void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
  6413. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  6414. uint16_t n = 0, len = (uint16_t) buflen;
  6415. while (n < len) n = w5500_r2(s, W5500_S0, 0x20); // Wait for space
  6416. uint16_t ptr = w5500_r2(s, W5500_S0, 0x24); // Get write pointer
  6417. w5500_wn(s, W5500_TX0, ptr, (void *) buf, len); // Write data
  6418. w5500_w2(s, W5500_S0, 0x24, (uint16_t) (ptr + len)); // Advance write pointer
  6419. w5500_w1(s, W5500_S0, 1, 0x20); // Sock0 CR -> SEND
  6420. for (int i = 0; i < 40; i++) {
  6421. uint8_t ir = w5500_r1(s, W5500_S0, 2); // Read S0 IR
  6422. if (ir == 0) continue;
  6423. // printf("IR %d, len=%d, free=%d, ptr %d\n", ir, (int) len, (int) n, ptr);
  6424. w5500_w1(s, W5500_S0, 2, ir); // Write S0 IR: clear it!
  6425. if (ir & 8) len = 0; // Timeout. Report error
  6426. if (ir & (16 | 8)) break; // Stop on SEND_OK or timeout
  6427. }
  6428. return len;
  6429. }
  6430. static bool w5500_init(struct mg_tcpip_if *ifp) {
  6431. struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
  6432. s->end(s->spi);
  6433. w5500_w1(s, W5500_CR, 0, 0x80); // Reset chip: CR -> 0x80
  6434. w5500_w1(s, W5500_CR, 0x2e, 0); // CR PHYCFGR -> reset
  6435. w5500_w1(s, W5500_CR, 0x2e, 0xf8); // CR PHYCFGR -> set
  6436. // w5500_wn(s, W5500_CR, 9, s->mac, 6); // Set source MAC
  6437. w5500_w1(s, W5500_S0, 0x1e, 16); // Sock0 RX buf size
  6438. w5500_w1(s, W5500_S0, 0x1f, 16); // Sock0 TX buf size
  6439. w5500_w1(s, W5500_S0, 0, 4); // Sock0 MR -> MACRAW
  6440. w5500_w1(s, W5500_S0, 1, 1); // Sock0 CR -> OPEN
  6441. return w5500_r1(s, W5500_S0, 3) == 0x42; // Sock0 SR == MACRAW
  6442. }
  6443. static bool w5500_up(struct mg_tcpip_if *ifp) {
  6444. struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
  6445. uint8_t phycfgr = w5500_r1(spi, W5500_CR, 0x2e);
  6446. return phycfgr & 1; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up)
  6447. }
  6448. struct mg_tcpip_driver mg_tcpip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, w5500_up};
  6449. #endif
  6450. #ifdef MG_ENABLE_LINES
  6451. #line 1 "src/tcpip/tcpip.c"
  6452. #endif
  6453. #if MG_ENABLE_TCPIP
  6454. #define MG_EPHEMERAL_PORT_BASE 32768
  6455. #define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
  6456. #ifndef MIP_TCP_KEEPALIVE_MS
  6457. #define MIP_TCP_KEEPALIVE_MS 45000 // TCP keep-alive period, ms
  6458. #endif
  6459. #define MIP_TCP_ACK_MS 150 // Timeout for ACKing
  6460. struct connstate {
  6461. uint32_t seq, ack; // TCP seq/ack counters
  6462. uint64_t timer; // TCP keep-alive / ACK timer
  6463. uint8_t mac[6]; // Peer MAC address
  6464. uint8_t ttype; // Timer type. 0: ack, 1: keep-alive
  6465. #define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive
  6466. #define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon
  6467. uint8_t tmiss; // Number of keep-alive misses
  6468. struct mg_iobuf raw; // For TLS only. Incoming raw data
  6469. };
  6470. #pragma pack(push, 1)
  6471. struct lcp {
  6472. uint8_t addr, ctrl, proto[2], code, id, len[2];
  6473. };
  6474. struct eth {
  6475. uint8_t dst[6]; // Destination MAC address
  6476. uint8_t src[6]; // Source MAC address
  6477. uint16_t type; // Ethernet type
  6478. };
  6479. struct ip {
  6480. uint8_t ver; // Version
  6481. uint8_t tos; // Unused
  6482. uint16_t len; // Length
  6483. uint16_t id; // Unused
  6484. uint16_t frag; // Fragmentation
  6485. uint8_t ttl; // Time to live
  6486. uint8_t proto; // Upper level protocol
  6487. uint16_t csum; // Checksum
  6488. uint32_t src; // Source IP
  6489. uint32_t dst; // Destination IP
  6490. };
  6491. struct ip6 {
  6492. uint8_t ver; // Version
  6493. uint8_t opts[3]; // Options
  6494. uint16_t len; // Length
  6495. uint8_t proto; // Upper level protocol
  6496. uint8_t ttl; // Time to live
  6497. uint8_t src[16]; // Source IP
  6498. uint8_t dst[16]; // Destination IP
  6499. };
  6500. struct icmp {
  6501. uint8_t type;
  6502. uint8_t code;
  6503. uint16_t csum;
  6504. };
  6505. struct arp {
  6506. uint16_t fmt; // Format of hardware address
  6507. uint16_t pro; // Format of protocol address
  6508. uint8_t hlen; // Length of hardware address
  6509. uint8_t plen; // Length of protocol address
  6510. uint16_t op; // Operation
  6511. uint8_t sha[6]; // Sender hardware address
  6512. uint32_t spa; // Sender protocol address
  6513. uint8_t tha[6]; // Target hardware address
  6514. uint32_t tpa; // Target protocol address
  6515. };
  6516. struct tcp {
  6517. uint16_t sport; // Source port
  6518. uint16_t dport; // Destination port
  6519. uint32_t seq; // Sequence number
  6520. uint32_t ack; // Acknowledgement number
  6521. uint8_t off; // Data offset
  6522. uint8_t flags; // TCP flags
  6523. #define TH_FIN 0x01
  6524. #define TH_SYN 0x02
  6525. #define TH_RST 0x04
  6526. #define TH_PUSH 0x08
  6527. #define TH_ACK 0x10
  6528. #define TH_URG 0x20
  6529. #define TH_ECE 0x40
  6530. #define TH_CWR 0x80
  6531. uint16_t win; // Window
  6532. uint16_t csum; // Checksum
  6533. uint16_t urp; // Urgent pointer
  6534. };
  6535. struct udp {
  6536. uint16_t sport; // Source port
  6537. uint16_t dport; // Destination port
  6538. uint16_t len; // UDP length
  6539. uint16_t csum; // UDP checksum
  6540. };
  6541. struct dhcp {
  6542. uint8_t op, htype, hlen, hops;
  6543. uint32_t xid;
  6544. uint16_t secs, flags;
  6545. uint32_t ciaddr, yiaddr, siaddr, giaddr;
  6546. uint8_t hwaddr[208];
  6547. uint32_t magic;
  6548. uint8_t options[32];
  6549. };
  6550. #pragma pack(pop)
  6551. struct pkt {
  6552. struct mg_str raw; // Raw packet data
  6553. struct mg_str pay; // Payload data
  6554. struct eth *eth;
  6555. struct llc *llc;
  6556. struct arp *arp;
  6557. struct ip *ip;
  6558. struct ip6 *ip6;
  6559. struct icmp *icmp;
  6560. struct tcp *tcp;
  6561. struct udp *udp;
  6562. struct dhcp *dhcp;
  6563. };
  6564. static void mkpay(struct pkt *pkt, void *p) {
  6565. pkt->pay =
  6566. mg_str_n((char *) p, (size_t) (&pkt->raw.ptr[pkt->raw.len] - (char *) p));
  6567. }
  6568. static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
  6569. const uint8_t *p = (const uint8_t *) buf;
  6570. for (size_t i = 0; i < len; i++) sum += i & 1 ? p[i] : (uint32_t) (p[i] << 8);
  6571. return sum;
  6572. }
  6573. static uint16_t csumfin(uint32_t sum) {
  6574. while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
  6575. return mg_htons(~sum & 0xffff);
  6576. }
  6577. static uint16_t ipcsum(const void *buf, size_t len) {
  6578. uint32_t sum = csumup(0, buf, len);
  6579. return csumfin(sum);
  6580. }
  6581. static size_t ether_output(struct mg_tcpip_if *ifp, size_t len) {
  6582. // size_t min = 64; // Pad short frames to 64 bytes (minimum Ethernet size)
  6583. // if (len < min) memset(ifp->tx.ptr + len, 0, min - len), len = min;
  6584. // mg_hexdump(ifp->tx.ptr, len);
  6585. size_t n = ifp->driver->tx(ifp->tx.ptr, len, ifp);
  6586. if (n == len) ifp->nsent++;
  6587. return n;
  6588. }
  6589. static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
  6590. struct eth *eth = (struct eth *) ifp->tx.ptr;
  6591. struct arp *arp = (struct arp *) (eth + 1);
  6592. memset(eth->dst, 255, sizeof(eth->dst));
  6593. memcpy(eth->src, ifp->mac, sizeof(eth->src));
  6594. eth->type = mg_htons(0x806);
  6595. memset(arp, 0, sizeof(*arp));
  6596. arp->fmt = mg_htons(1), arp->pro = mg_htons(0x800), arp->hlen = 6,
  6597. arp->plen = 4;
  6598. arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
  6599. memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
  6600. ether_output(ifp, PDIFF(eth, arp + 1));
  6601. }
  6602. static void onstatechange(struct mg_tcpip_if *ifp) {
  6603. if (ifp->state == MG_TCPIP_STATE_READY) {
  6604. MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
  6605. MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw));
  6606. if (ifp->lease_expire > ifp->now) {
  6607. MG_INFO(
  6608. (" Lease: %lld sec", (ifp->lease_expire - ifp->now) / 1000));
  6609. }
  6610. arp_ask(ifp, ifp->gw);
  6611. } else if (ifp->state == MG_TCPIP_STATE_UP) {
  6612. MG_ERROR(("Link up"));
  6613. srand((unsigned int) mg_millis());
  6614. } else if (ifp->state == MG_TCPIP_STATE_DOWN) {
  6615. MG_ERROR(("Link down"));
  6616. }
  6617. }
  6618. static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
  6619. uint8_t proto, uint32_t ip_src, uint32_t ip_dst,
  6620. size_t plen) {
  6621. struct eth *eth = (struct eth *) ifp->tx.ptr;
  6622. struct ip *ip = (struct ip *) (eth + 1);
  6623. memcpy(eth->dst, mac_dst, sizeof(eth->dst));
  6624. memcpy(eth->src, ifp->mac, sizeof(eth->src)); // Use our MAC
  6625. eth->type = mg_htons(0x800);
  6626. memset(ip, 0, sizeof(*ip));
  6627. ip->ver = 0x45; // Version 4, header length 5 words
  6628. ip->frag = 0x40; // Don't fragment
  6629. ip->len = mg_htons((uint16_t) (sizeof(*ip) + plen));
  6630. ip->ttl = 64;
  6631. ip->proto = proto;
  6632. ip->src = ip_src;
  6633. ip->dst = ip_dst;
  6634. ip->csum = ipcsum(ip, sizeof(*ip));
  6635. return ip;
  6636. }
  6637. static void tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
  6638. uint16_t sport, uint32_t ip_dst, uint16_t dport,
  6639. const void *buf, size_t len) {
  6640. struct ip *ip =
  6641. tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp));
  6642. struct udp *udp = (struct udp *) (ip + 1);
  6643. // MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
  6644. udp->sport = sport;
  6645. udp->dport = dport;
  6646. udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
  6647. udp->csum = 0;
  6648. uint32_t cs = csumup(0, udp, sizeof(*udp));
  6649. cs = csumup(cs, buf, len);
  6650. cs = csumup(cs, &ip->src, sizeof(ip->src));
  6651. cs = csumup(cs, &ip->dst, sizeof(ip->dst));
  6652. cs += (uint32_t) (ip->proto + sizeof(*udp) + len);
  6653. udp->csum = csumfin(cs);
  6654. memmove(udp + 1, buf, len);
  6655. // MG_DEBUG(("UDP LEN %d %d", (int) len, (int) ifp->frame_len));
  6656. ether_output(ifp, sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len);
  6657. }
  6658. static void tx_dhcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
  6659. uint32_t ip_dst, uint8_t *opts, size_t optslen) {
  6660. struct dhcp dhcp = {1, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
  6661. dhcp.magic = mg_htonl(0x63825363);
  6662. memcpy(&dhcp.hwaddr, ifp->mac, sizeof(ifp->mac));
  6663. memcpy(&dhcp.xid, ifp->mac + 2, sizeof(dhcp.xid));
  6664. memcpy(&dhcp.options, opts, optslen);
  6665. tx_udp(ifp, mac_dst, ip_src, mg_htons(68), ip_dst, mg_htons(67), &dhcp,
  6666. sizeof(dhcp));
  6667. }
  6668. static void tx_dhcp_request(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
  6669. uint32_t ip_src, uint32_t ip_dst) {
  6670. uint8_t opts[] = {
  6671. 53, 1, 3, // Type: DHCP request
  6672. 55, 2, 1, 3, // GW and mask
  6673. 12, 3, 'm', 'i', 'p', // Host name: "mip"
  6674. 54, 4, 0, 0, 0, 0, // DHCP server ID
  6675. 50, 4, 0, 0, 0, 0, // Requested IP
  6676. 255 // End of options
  6677. };
  6678. memcpy(opts + 14, &ip_dst, sizeof(ip_dst));
  6679. memcpy(opts + 20, &ip_src, sizeof(ip_src));
  6680. tx_dhcp(ifp, mac_dst, ip_src, ip_dst, opts, sizeof(opts));
  6681. }
  6682. static void tx_dhcp_discover(struct mg_tcpip_if *ifp) {
  6683. uint8_t mac[6] = {255, 255, 255, 255, 255, 255};
  6684. uint8_t opts[] = {
  6685. 53, 1, 1, // Type: DHCP discover
  6686. 55, 2, 1, 3, // Parameters: ip, mask
  6687. 255 // End of options
  6688. };
  6689. tx_dhcp(ifp, mac, 0, 0xffffffff, opts, sizeof(opts));
  6690. MG_DEBUG(("DHCP discover sent"));
  6691. }
  6692. static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
  6693. bool lsn) {
  6694. struct mg_connection *c = NULL;
  6695. for (c = mgr->conns; c != NULL; c = c->next) {
  6696. if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) break;
  6697. if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport &&
  6698. lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport))
  6699. break;
  6700. }
  6701. return c;
  6702. }
  6703. static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  6704. if (pkt->arp->op == mg_htons(1) && pkt->arp->tpa == ifp->ip) {
  6705. // ARP request. Make a response, then send
  6706. // MG_DEBUG(("ARP op %d %M: %M", mg_ntohs(pkt->arp->op), mg_print_ip4,
  6707. // &pkt->arp->spa, mg_print_ip4, &pkt->arp->tpa));
  6708. struct eth *eth = (struct eth *) ifp->tx.ptr;
  6709. struct arp *arp = (struct arp *) (eth + 1);
  6710. memcpy(eth->dst, pkt->eth->src, sizeof(eth->dst));
  6711. memcpy(eth->src, ifp->mac, sizeof(eth->src));
  6712. eth->type = mg_htons(0x806);
  6713. *arp = *pkt->arp;
  6714. arp->op = mg_htons(2);
  6715. memcpy(arp->tha, pkt->arp->sha, sizeof(pkt->arp->tha));
  6716. memcpy(arp->sha, ifp->mac, sizeof(pkt->arp->sha));
  6717. arp->tpa = pkt->arp->spa;
  6718. arp->spa = ifp->ip;
  6719. MG_DEBUG(("ARP: tell %M we're %M", mg_print_ip4, &arp->tpa, mg_print_ip4,
  6720. &ifp->ip));
  6721. ether_output(ifp, PDIFF(eth, arp + 1));
  6722. } else if (pkt->arp->op == mg_htons(2)) {
  6723. if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
  6724. if (pkt->arp->spa == ifp->gw) {
  6725. // Got response for the GW ARP request. Set ifp->gwmac
  6726. memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
  6727. } else {
  6728. struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
  6729. if (c != NULL && c->is_arplooking) {
  6730. struct connstate *s = (struct connstate *) (c + 1);
  6731. memcpy(s->mac, pkt->arp->sha, sizeof(s->mac));
  6732. MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, &c->rem.ip,
  6733. mg_print_mac, s->mac));
  6734. c->is_arplooking = 0;
  6735. }
  6736. }
  6737. }
  6738. }
  6739. static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  6740. // MG_DEBUG(("ICMP %d", (int) len));
  6741. if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) {
  6742. size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
  6743. size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
  6744. if (plen > space) plen = space;
  6745. struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
  6746. sizeof(struct icmp) + plen);
  6747. struct icmp *icmp = (struct icmp *) (ip + 1);
  6748. memset(icmp, 0, sizeof(*icmp)); // Set csum to 0
  6749. memcpy(icmp + 1, pkt->pay.ptr, plen); // Copy RX payload to TX
  6750. icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen);
  6751. ether_output(ifp, hlen + plen);
  6752. }
  6753. }
  6754. static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  6755. uint32_t ip = 0, gw = 0, mask = 0;
  6756. uint8_t *p = pkt->dhcp->options,
  6757. *end = (uint8_t *) &pkt->raw.ptr[pkt->raw.len];
  6758. if (end < (uint8_t *) (pkt->dhcp + 1)) return;
  6759. while (p + 1 < end && p[0] != 255) { // Parse options
  6760. if (p[0] == 1 && p[1] == sizeof(ifp->mask) && p + 6 < end) { // Mask
  6761. memcpy(&mask, p + 2, sizeof(mask));
  6762. } else if (p[0] == 3 && p[1] == sizeof(ifp->gw) && p + 6 < end) { // GW
  6763. memcpy(&gw, p + 2, sizeof(gw));
  6764. ip = pkt->dhcp->yiaddr;
  6765. } else if (p[0] == 51 && p[1] == 4 && p + 6 < end) { // Lease
  6766. uint32_t lease = 0;
  6767. memcpy(&lease, p + 2, sizeof(lease));
  6768. ifp->lease_expire = ifp->now + mg_ntohl(lease) * 1000;
  6769. }
  6770. p += p[1] + 2;
  6771. }
  6772. if (ip && mask && gw && ifp->ip == 0) {
  6773. memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
  6774. ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
  6775. ifp->state = MG_TCPIP_STATE_READY;
  6776. onstatechange(ifp);
  6777. tx_dhcp_request(ifp, pkt->eth->src, ip, pkt->dhcp->siaddr);
  6778. uint64_t rand;
  6779. mg_random(&rand, sizeof(rand));
  6780. srand((unsigned int) (rand + mg_millis()));
  6781. }
  6782. }
  6783. // Simple DHCP server that assigns a next IP address: ifp->ip + 1
  6784. static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  6785. uint8_t op = 0, *p = pkt->dhcp->options,
  6786. *end = (uint8_t *) &pkt->raw.ptr[pkt->raw.len];
  6787. if (end < (uint8_t *) (pkt->dhcp + 1)) return;
  6788. // struct dhcp *req = pkt->dhcp;
  6789. struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
  6790. res.yiaddr = ifp->ip;
  6791. ((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1
  6792. while (p + 1 < end && p[0] != 255) { // Parse options
  6793. if (p[0] == 53 && p[1] == 1 && p + 2 < end) { // Message type
  6794. op = p[2];
  6795. }
  6796. p += p[1] + 2;
  6797. }
  6798. if (op == 1 || op == 3) { // DHCP Discover or DHCP Request
  6799. uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK
  6800. uint8_t opts[] = {
  6801. 53, 1, msg, // Message type
  6802. 1, 4, 0, 0, 0, 0, // Subnet mask
  6803. 54, 4, 0, 0, 0, 0, // Server ID
  6804. 12, 3, 'm', 'i', 'p', // Host name: "mip"
  6805. 51, 4, 255, 255, 255, 255, // Lease time
  6806. 255 // End of options
  6807. };
  6808. memcpy(&res.hwaddr, pkt->dhcp->hwaddr, 6);
  6809. memcpy(opts + 5, &ifp->mask, sizeof(ifp->mask));
  6810. memcpy(opts + 11, &ifp->ip, sizeof(ifp->ip));
  6811. memcpy(&res.options, opts, sizeof(opts));
  6812. res.magic = pkt->dhcp->magic;
  6813. res.xid = pkt->dhcp->xid;
  6814. // memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
  6815. tx_udp(ifp, pkt->eth->src, ifp->ip, mg_htons(67),
  6816. op == 1 ? ~0U : res.yiaddr, mg_htons(68), &res, sizeof(res));
  6817. }
  6818. }
  6819. static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  6820. struct mg_connection *c = getpeer(ifp->mgr, pkt, true);
  6821. if (c == NULL) {
  6822. // No UDP listener on this port. Should send ICMP, but keep silent.
  6823. } else if (c != NULL) {
  6824. c->rem.port = pkt->udp->sport;
  6825. c->rem.ip = pkt->ip->src;
  6826. if (c->recv.len >= MG_MAX_RECV_SIZE) {
  6827. mg_error(c, "max_recv_buf_size reached");
  6828. } else if (c->recv.size - c->recv.len < pkt->pay.len &&
  6829. !mg_iobuf_resize(&c->recv, c->recv.len + pkt->pay.len)) {
  6830. mg_error(c, "oom");
  6831. } else {
  6832. memcpy(&c->recv.buf[c->recv.len], pkt->pay.ptr, pkt->pay.len);
  6833. c->recv.len += pkt->pay.len;
  6834. mg_call(c, MG_EV_READ, &pkt->pay.len);
  6835. }
  6836. }
  6837. }
  6838. static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
  6839. uint8_t flags, uint16_t sport, uint16_t dport,
  6840. uint32_t seq, uint32_t ack, const void *buf, size_t len) {
  6841. struct ip *ip =
  6842. tx_ip(ifp, dst_mac, 6, ifp->ip, dst_ip, sizeof(struct tcp) + len);
  6843. struct tcp *tcp = (struct tcp *) (ip + 1);
  6844. memset(tcp, 0, sizeof(*tcp));
  6845. if (buf != NULL && len) memmove(tcp + 1, buf, len);
  6846. tcp->sport = sport;
  6847. tcp->dport = dport;
  6848. tcp->seq = seq;
  6849. tcp->ack = ack;
  6850. tcp->flags = flags;
  6851. tcp->win = mg_htons(8192);
  6852. tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
  6853. uint32_t cs = 0;
  6854. uint16_t n = (uint16_t) (sizeof(*tcp) + len);
  6855. uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
  6856. cs = csumup(cs, tcp, n);
  6857. cs = csumup(cs, &ip->src, sizeof(ip->src));
  6858. cs = csumup(cs, &ip->dst, sizeof(ip->dst));
  6859. cs = csumup(cs, pseudo, sizeof(pseudo));
  6860. tcp->csum = csumfin(cs);
  6861. MG_DEBUG(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
  6862. mg_ntohs(tcp->sport), mg_print_ip4, &ip->dst, mg_ntohs(tcp->dport),
  6863. tcp->flags, (int) len));
  6864. return ether_output(ifp, PDIFF(ifp->tx.ptr, tcp + 1) + len);
  6865. }
  6866. static size_t tx_tcp_pkt(struct mg_tcpip_if *ifp, struct pkt *pkt,
  6867. uint8_t flags, uint32_t seq, const void *buf,
  6868. size_t len) {
  6869. uint32_t delta = (pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0;
  6870. return tx_tcp(ifp, pkt->eth->src, pkt->ip->src, flags, pkt->tcp->dport,
  6871. pkt->tcp->sport, seq, mg_htonl(mg_ntohl(pkt->tcp->seq) + delta),
  6872. buf, len);
  6873. }
  6874. static void settmout(struct mg_connection *c, uint8_t type) {
  6875. struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
  6876. struct connstate *s = (struct connstate *) (c + 1);
  6877. unsigned n = type == MIP_TTYPE_ACK ? MIP_TCP_ACK_MS : MIP_TCP_KEEPALIVE_MS;
  6878. s->timer = ifp->now + n;
  6879. s->ttype = type;
  6880. MG_VERBOSE(("%lu %d -> %llx", c->id, type, s->timer));
  6881. }
  6882. static struct mg_connection *accept_conn(struct mg_connection *lsn,
  6883. struct pkt *pkt) {
  6884. struct mg_connection *c = mg_alloc_conn(lsn->mgr);
  6885. struct connstate *s = (struct connstate *) (c + 1);
  6886. s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
  6887. memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
  6888. settmout(c, MIP_TTYPE_KEEPALIVE);
  6889. c->rem.ip = pkt->ip->src;
  6890. c->rem.port = pkt->tcp->sport;
  6891. MG_DEBUG(("%lu accepted %M", c->id, mg_print_ip_port, &c->rem));
  6892. LIST_ADD_HEAD(struct mg_connection, &lsn->mgr->conns, c);
  6893. c->is_accepted = 1;
  6894. c->is_hexdumping = lsn->is_hexdumping;
  6895. c->pfn = lsn->pfn;
  6896. c->loc = lsn->loc;
  6897. c->pfn_data = lsn->pfn_data;
  6898. c->fn = lsn->fn;
  6899. c->fn_data = lsn->fn_data;
  6900. mg_call(c, MG_EV_OPEN, NULL);
  6901. mg_call(c, MG_EV_ACCEPT, NULL);
  6902. return c;
  6903. }
  6904. long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
  6905. struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
  6906. struct connstate *s = (struct connstate *) (c + 1);
  6907. size_t max_headers_len = 14 + 24 /* max IP */ + 60 /* max TCP */;
  6908. if (len + max_headers_len > ifp->tx.len) len = ifp->tx.len - max_headers_len;
  6909. if (tx_tcp(ifp, s->mac, c->rem.ip, TH_PUSH | TH_ACK, c->loc.port, c->rem.port,
  6910. mg_htonl(s->seq), mg_htonl(s->ack), buf, len) > 0) {
  6911. s->seq += (uint32_t) len;
  6912. if (s->ttype == MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_KEEPALIVE);
  6913. } else {
  6914. return MG_IO_ERR;
  6915. }
  6916. return (long) len;
  6917. }
  6918. long mg_io_recv(struct mg_connection *c, void *buf, size_t len) {
  6919. struct connstate *s = (struct connstate *) (c + 1);
  6920. if (s->raw.len == 0) return MG_IO_WAIT;
  6921. if (len > s->raw.len) len = s->raw.len;
  6922. memcpy(buf, s->raw.buf, len);
  6923. mg_iobuf_del(&s->raw, 0, len);
  6924. MG_DEBUG(("%lu", len));
  6925. return (long) len;
  6926. }
  6927. static void read_conn(struct mg_connection *c, struct pkt *pkt) {
  6928. struct connstate *s = (struct connstate *) (c + 1);
  6929. struct mg_iobuf *io = c->is_tls ? &s->raw : &c->recv;
  6930. uint32_t seq = mg_ntohl(pkt->tcp->seq);
  6931. s->raw.align = c->recv.align;
  6932. if (pkt->tcp->flags & TH_FIN) {
  6933. s->ack = mg_htonl(pkt->tcp->seq) + 1, s->seq = mg_htonl(pkt->tcp->ack);
  6934. c->is_closing = 1;
  6935. } else if (pkt->pay.len == 0) {
  6936. // TODO(cpq): handle this peer's ACK
  6937. } else if (seq != s->ack) {
  6938. uint32_t ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
  6939. if (s->ack == ack) {
  6940. MG_VERBOSE(("ignoring duplicate pkt"));
  6941. } else {
  6942. // TODO(cpq): peer sent us SEQ which we don't expect. Retransmit rather
  6943. // than close this connection
  6944. mg_error(c, "SEQ != ACK: %x %x %x", seq, s->ack, ack);
  6945. }
  6946. } else if (io->size - io->len < pkt->pay.len &&
  6947. !mg_iobuf_resize(io, io->len + pkt->pay.len)) {
  6948. mg_error(c, "oom");
  6949. } else {
  6950. // Copy TCP payload into the IO buffer. If the connection is plain text, we
  6951. // copy to c->recv. If the connection is TLS, this data is encrypted,
  6952. // therefore we copy that encrypted data to the s->raw iobuffer instead,
  6953. // and then call mg_tls_recv() to decrypt it. NOTE: mg_tls_recv() will
  6954. // call back mg_io_recv() which grabs raw data from s->raw
  6955. memcpy(&io->buf[io->len], pkt->pay.ptr, pkt->pay.len);
  6956. io->len += pkt->pay.len;
  6957. MG_DEBUG(("%lu SEQ %x -> %x", c->id, mg_htonl(pkt->tcp->seq), s->ack));
  6958. // Advance ACK counter
  6959. s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
  6960. #if 0
  6961. // Send ACK immediately
  6962. MG_DEBUG((" imm ACK", c->id, mg_htonl(pkt->tcp->seq), s->ack));
  6963. tx_tcp((struct mg_tcpip_if *) c->mgr->priv, c->rem.ip, TH_ACK, c->loc.port,
  6964. c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
  6965. #else
  6966. // if not already running, setup a timer to send an ACK later
  6967. if (s->ttype != MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_ACK);
  6968. #endif
  6969. if (c->is_tls) {
  6970. // TLS connection. Make room for decrypted data in c->recv
  6971. io = &c->recv;
  6972. if (io->size - io->len < pkt->pay.len &&
  6973. !mg_iobuf_resize(io, io->len + pkt->pay.len)) {
  6974. mg_error(c, "oom");
  6975. } else {
  6976. // Decrypt data directly into c->recv
  6977. long n = mg_tls_recv(c, &io->buf[io->len], io->size - io->len);
  6978. if (n == MG_IO_ERR) {
  6979. mg_error(c, "TLS recv error");
  6980. } else if (n > 0) {
  6981. // Decrypted successfully - trigger MG_EV_READ
  6982. io->len += (size_t) n;
  6983. mg_call(c, MG_EV_READ, &n);
  6984. }
  6985. }
  6986. } else {
  6987. // Plain text connection, data is already in c->recv, trigger MG_EV_READ
  6988. mg_call(c, MG_EV_READ, &pkt->pay.len);
  6989. }
  6990. }
  6991. }
  6992. static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  6993. struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
  6994. struct connstate *s = c == NULL ? NULL : (struct connstate *) (c + 1);
  6995. #if 0
  6996. MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len));
  6997. #endif
  6998. if (c != NULL && c->is_connecting && pkt->tcp->flags & (TH_SYN | TH_ACK)) {
  6999. s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1;
  7000. tx_tcp_pkt(ifp, pkt, TH_ACK, pkt->tcp->ack, NULL, 0);
  7001. c->is_connecting = 0; // Client connected
  7002. settmout(c, MIP_TTYPE_KEEPALIVE);
  7003. mg_call(c, MG_EV_CONNECT, NULL); // Let user know
  7004. } else if (c != NULL && c->is_connecting) {
  7005. tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  7006. } else if (c != NULL && pkt->tcp->flags & TH_RST) {
  7007. mg_error(c, "peer RST"); // RFC-1122 4.2.2.13
  7008. } else if (c != NULL) {
  7009. #if 0
  7010. MG_DEBUG(("%lu %d %M:%hu -> %M:%hu", c->id, (int) pkt->raw.len,
  7011. mg_print_ip4, &pkt->ip->src, mg_ntohs(pkt->tcp->sport),
  7012. mg_print_ip4, &pkt->ip->dst, mg_ntohs(pkt->tcp->dport)));
  7013. mg_hexdump(pkt->pay.buf, pkt->pay.len);
  7014. #endif
  7015. s->tmiss = 0; // Reset missed keep-alive counter
  7016. if (s->ttype == MIP_TTYPE_KEEPALIVE) // Advance keep-alive timer
  7017. settmout(c,
  7018. MIP_TTYPE_KEEPALIVE); // unless a former ACK timeout is pending
  7019. read_conn(c, pkt); // Override timer with ACK timeout if needed
  7020. } else if ((c = getpeer(ifp->mgr, pkt, true)) == NULL) {
  7021. tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  7022. } else if (pkt->tcp->flags & TH_RST) {
  7023. if (c->is_accepted) mg_error(c, "peer RST"); // RFC-1122 4.2.2.13
  7024. // ignore RST if not connected
  7025. } else if (pkt->tcp->flags & TH_SYN) {
  7026. // Use peer's source port as ISN, in order to recognise the handshake
  7027. uint32_t isn = mg_htonl((uint32_t) mg_ntohs(pkt->tcp->sport));
  7028. tx_tcp_pkt(ifp, pkt, TH_SYN | TH_ACK, isn, NULL, 0);
  7029. } else if (pkt->tcp->flags & TH_FIN) {
  7030. tx_tcp_pkt(ifp, pkt, TH_FIN | TH_ACK, pkt->tcp->ack, NULL, 0);
  7031. } else if (mg_htonl(pkt->tcp->ack) == mg_htons(pkt->tcp->sport) + 1U) {
  7032. accept_conn(c, pkt);
  7033. } else if (!c->is_accepted) { // no peer
  7034. tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  7035. } else {
  7036. // MG_DEBUG(("dropped silently.."));
  7037. }
  7038. }
  7039. static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  7040. if (pkt->ip->proto == 1) {
  7041. pkt->icmp = (struct icmp *) (pkt->ip + 1);
  7042. if (pkt->pay.len < sizeof(*pkt->icmp)) return;
  7043. mkpay(pkt, pkt->icmp + 1);
  7044. rx_icmp(ifp, pkt);
  7045. } else if (pkt->ip->proto == 17) {
  7046. pkt->udp = (struct udp *) (pkt->ip + 1);
  7047. if (pkt->pay.len < sizeof(*pkt->udp)) return;
  7048. mkpay(pkt, pkt->udp + 1);
  7049. MG_DEBUG(("UDP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
  7050. mg_ntohs(pkt->udp->sport), mg_print_ip4, &pkt->ip->dst,
  7051. mg_ntohs(pkt->udp->dport), (int) pkt->pay.len));
  7052. if (pkt->udp->dport == mg_htons(68)) {
  7053. pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
  7054. mkpay(pkt, pkt->dhcp + 1);
  7055. rx_dhcp_client(ifp, pkt);
  7056. } else if (ifp->enable_dhcp_server && pkt->udp->dport == mg_htons(67)) {
  7057. pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
  7058. mkpay(pkt, pkt->dhcp + 1);
  7059. rx_dhcp_server(ifp, pkt);
  7060. } else {
  7061. rx_udp(ifp, pkt);
  7062. }
  7063. } else if (pkt->ip->proto == 6) {
  7064. pkt->tcp = (struct tcp *) (pkt->ip + 1);
  7065. if (pkt->pay.len < sizeof(*pkt->tcp)) return;
  7066. mkpay(pkt, pkt->tcp + 1);
  7067. uint16_t iplen = mg_ntohs(pkt->ip->len);
  7068. uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
  7069. if (iplen >= off) pkt->pay.len = (size_t) (iplen - off);
  7070. MG_DEBUG(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
  7071. mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst,
  7072. mg_ntohs(pkt->tcp->dport), (int) pkt->pay.len));
  7073. rx_tcp(ifp, pkt);
  7074. }
  7075. }
  7076. static void rx_ip6(struct mg_tcpip_if *ifp, struct pkt *pkt) {
  7077. // MG_DEBUG(("IP %d", (int) len));
  7078. if (pkt->ip6->proto == 1 || pkt->ip6->proto == 58) {
  7079. pkt->icmp = (struct icmp *) (pkt->ip6 + 1);
  7080. if (pkt->pay.len < sizeof(*pkt->icmp)) return;
  7081. mkpay(pkt, pkt->icmp + 1);
  7082. rx_icmp(ifp, pkt);
  7083. } else if (pkt->ip6->proto == 17) {
  7084. pkt->udp = (struct udp *) (pkt->ip6 + 1);
  7085. if (pkt->pay.len < sizeof(*pkt->udp)) return;
  7086. // MG_DEBUG((" UDP %u %u -> %u", len, mg_htons(udp->sport),
  7087. // mg_htons(udp->dport)));
  7088. mkpay(pkt, pkt->udp + 1);
  7089. }
  7090. }
  7091. static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
  7092. const uint8_t broadcast[] = {255, 255, 255, 255, 255, 255};
  7093. struct pkt pkt;
  7094. memset(&pkt, 0, sizeof(pkt));
  7095. pkt.raw.ptr = (char *) buf;
  7096. pkt.raw.len = len;
  7097. pkt.eth = (struct eth *) buf;
  7098. if (pkt.raw.len < sizeof(*pkt.eth)) return; // Truncated - runt?
  7099. if (ifp->enable_mac_check &&
  7100. memcmp(pkt.eth->dst, ifp->mac, sizeof(pkt.eth->dst)) != 0 &&
  7101. memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0)
  7102. return;
  7103. if (ifp->enable_crc32_check && len > 4) {
  7104. len -= 4; // TODO(scaprile): check on bigendian
  7105. uint32_t crc = mg_crc32(0, (const char *) buf, len);
  7106. if (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return;
  7107. }
  7108. if (pkt.eth->type == mg_htons(0x806)) {
  7109. pkt.arp = (struct arp *) (pkt.eth + 1);
  7110. if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) return; // Truncated
  7111. rx_arp(ifp, &pkt);
  7112. } else if (pkt.eth->type == mg_htons(0x86dd)) {
  7113. pkt.ip6 = (struct ip6 *) (pkt.eth + 1);
  7114. if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip6)) return; // Truncated
  7115. if ((pkt.ip6->ver >> 4) != 0x6) return; // Not IP
  7116. mkpay(&pkt, pkt.ip6 + 1);
  7117. rx_ip6(ifp, &pkt);
  7118. } else if (pkt.eth->type == mg_htons(0x800)) {
  7119. pkt.ip = (struct ip *) (pkt.eth + 1);
  7120. if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) return; // Truncated
  7121. // Truncate frame to what IP header tells us
  7122. if ((size_t) mg_ntohs(pkt.ip->len) + sizeof(struct eth) < pkt.raw.len) {
  7123. pkt.raw.len = (size_t) mg_ntohs(pkt.ip->len) + sizeof(struct eth);
  7124. }
  7125. if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) return; // Truncated
  7126. if ((pkt.ip->ver >> 4) != 4) return; // Not IP
  7127. mkpay(&pkt, pkt.ip + 1);
  7128. rx_ip(ifp, &pkt);
  7129. } else {
  7130. MG_DEBUG((" Unknown eth type %x", mg_htons(pkt.eth->type)));
  7131. mg_hexdump(buf, len >= 16 ? 16 : len);
  7132. }
  7133. }
  7134. static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) {
  7135. if (ifp == NULL || ifp->driver == NULL) return;
  7136. bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, uptime_ms);
  7137. ifp->now = uptime_ms;
  7138. // Handle physical interface up/down status
  7139. if (expired_1000ms && ifp->driver->up) {
  7140. bool up = ifp->driver->up(ifp);
  7141. bool current = ifp->state != MG_TCPIP_STATE_DOWN;
  7142. if (up != current) {
  7143. ifp->state = up == false ? MG_TCPIP_STATE_DOWN
  7144. : ifp->enable_dhcp_client ? MG_TCPIP_STATE_UP
  7145. : MG_TCPIP_STATE_READY;
  7146. if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
  7147. onstatechange(ifp);
  7148. }
  7149. }
  7150. if (ifp->state == MG_TCPIP_STATE_DOWN) return;
  7151. // If IP not configured, send DHCP
  7152. if (ifp->ip == 0 && expired_1000ms) tx_dhcp_discover(ifp);
  7153. // Read data from the network
  7154. if (ifp->driver->rx != NULL) { // Polling driver. We must call it
  7155. size_t len =
  7156. ifp->driver->rx(ifp->recv_queue.buf, ifp->recv_queue.size, ifp);
  7157. if (len > 0) mg_tcpip_rx(ifp, ifp->recv_queue.buf, len);
  7158. } else { // Interrupt-based driver. Fills recv queue itself
  7159. char *buf;
  7160. size_t len = mg_queue_next(&ifp->recv_queue, &buf);
  7161. if (len > 0) {
  7162. mg_tcpip_rx(ifp, buf, len);
  7163. mg_queue_del(&ifp->recv_queue, len);
  7164. }
  7165. }
  7166. // Process timeouts
  7167. for (struct mg_connection *c = ifp->mgr->conns; c != NULL; c = c->next) {
  7168. if (c->is_udp || c->is_listening) continue;
  7169. if (c->is_connecting || c->is_resolving) continue;
  7170. struct connstate *s = (struct connstate *) (c + 1);
  7171. if (uptime_ms > s->timer) {
  7172. if (s->ttype == MIP_TTYPE_ACK) {
  7173. MG_DEBUG(("%lu ack %x %x", c->id, s->seq, s->ack));
  7174. tx_tcp(ifp, s->mac, c->rem.ip, TH_ACK, c->loc.port, c->rem.port,
  7175. mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
  7176. } else {
  7177. if (s->tmiss++ > 2) {
  7178. mg_error(c, "keepalive");
  7179. } else {
  7180. MG_DEBUG(("%lu keepalive", c->id));
  7181. tx_tcp(ifp, s->mac, c->rem.ip, TH_ACK, c->loc.port, c->rem.port,
  7182. mg_htonl(s->seq - 1), mg_htonl(s->ack), "", 0);
  7183. }
  7184. }
  7185. settmout(c, MIP_TTYPE_KEEPALIVE);
  7186. }
  7187. }
  7188. }
  7189. // This function executes in interrupt context, thus it should copy data
  7190. // somewhere fast. Note that newlib's malloc is not thread safe, thus use
  7191. // our lock-free queue with preallocated buffer to copy data and return asap
  7192. void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp) {
  7193. char *p;
  7194. if (mg_queue_book(&ifp->recv_queue, &p, len) >= len) {
  7195. memcpy(p, buf, len);
  7196. mg_queue_add(&ifp->recv_queue, len);
  7197. ifp->nrecv++;
  7198. } else {
  7199. ifp->ndrop++;
  7200. }
  7201. }
  7202. void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
  7203. // If MAC address is not set, make a random one
  7204. if (ifp->mac[0] == 0 && ifp->mac[1] == 0 && ifp->mac[2] == 0 &&
  7205. ifp->mac[3] == 0 && ifp->mac[4] == 0 && ifp->mac[5] == 0) {
  7206. ifp->mac[0] = 0x02; // Locally administered, unicast
  7207. mg_random(&ifp->mac[1], sizeof(ifp->mac) - 1);
  7208. MG_INFO(("MAC not set. Generated random: %M", mg_print_mac, ifp->mac));
  7209. }
  7210. if (ifp->driver->init && !ifp->driver->init(ifp)) {
  7211. MG_ERROR(("driver init failed"));
  7212. } else {
  7213. size_t framesize = 1540;
  7214. ifp->tx.ptr = (char *) calloc(1, framesize), ifp->tx.len = framesize;
  7215. if (ifp->recv_queue.size == 0)
  7216. ifp->recv_queue.size = ifp->driver->rx ? framesize : 8192;
  7217. ifp->recv_queue.buf = (char *) calloc(1, ifp->recv_queue.size);
  7218. ifp->timer_1000ms = mg_millis();
  7219. mgr->priv = ifp;
  7220. ifp->mgr = mgr;
  7221. mgr->extraconnsize = sizeof(struct connstate);
  7222. if (ifp->ip == 0) ifp->enable_dhcp_client = true;
  7223. memset(ifp->gwmac, 255, sizeof(ifp->gwmac)); // Set to broadcast
  7224. mg_random(&ifp->eport, sizeof(ifp->eport)); // Random from 0 to 65535
  7225. ifp->eport |=
  7226. MG_EPHEMERAL_PORT_BASE; // Random from MG_EPHEMERAL_PORT_BASE to 65535
  7227. }
  7228. }
  7229. void mg_tcpip_free(struct mg_tcpip_if *ifp) {
  7230. free(ifp->recv_queue.buf);
  7231. free((char *) ifp->tx.ptr);
  7232. }
  7233. int mg_mkpipe(struct mg_mgr *m, mg_event_handler_t fn, void *d, bool udp) {
  7234. (void) m, (void) fn, (void) d, (void) udp;
  7235. MG_ERROR(("Not implemented"));
  7236. return -1;
  7237. }
  7238. static void send_syn(struct mg_connection *c) {
  7239. struct connstate *s = (struct connstate *) (c + 1);
  7240. uint32_t isn = mg_htonl((uint32_t) mg_ntohs(c->loc.port));
  7241. struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
  7242. tx_tcp(ifp, s->mac, c->rem.ip, TH_SYN, c->loc.port, c->rem.port, isn, 0, NULL,
  7243. 0);
  7244. }
  7245. void mg_connect_resolved(struct mg_connection *c) {
  7246. struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
  7247. c->is_resolving = 0;
  7248. if (ifp->eport < MG_EPHEMERAL_PORT_BASE) ifp->eport = MG_EPHEMERAL_PORT_BASE;
  7249. c->loc.ip = ifp->ip;
  7250. c->loc.port = mg_htons(ifp->eport++);
  7251. MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port,
  7252. &c->rem));
  7253. mg_call(c, MG_EV_RESOLVE, NULL);
  7254. if (((c->rem.ip & ifp->mask) == (ifp->ip & ifp->mask))) {
  7255. // If we're in the same LAN, fire an ARP lookup. TODO(cpq): handle this!
  7256. MG_DEBUG(("%lu ARP lookup...", c->id));
  7257. arp_ask(ifp, c->rem.ip);
  7258. c->is_arplooking = 1;
  7259. } else {
  7260. struct connstate *s = (struct connstate *) (c + 1);
  7261. memcpy(s->mac, ifp->gwmac, sizeof(ifp->gwmac));
  7262. if (c->is_udp) {
  7263. mg_call(c, MG_EV_CONNECT, NULL);
  7264. } else {
  7265. send_syn(c);
  7266. c->is_connecting = 1;
  7267. }
  7268. }
  7269. }
  7270. bool mg_open_listener(struct mg_connection *c, const char *url) {
  7271. c->loc.port = mg_htons(mg_url_port(url));
  7272. return true;
  7273. }
  7274. static void write_conn(struct mg_connection *c) {
  7275. long len = c->is_tls ? mg_tls_send(c, c->send.buf, c->send.len)
  7276. : mg_io_send(c, c->send.buf, c->send.len);
  7277. if (len > 0) {
  7278. mg_iobuf_del(&c->send, 0, (size_t) len);
  7279. mg_call(c, MG_EV_WRITE, &len);
  7280. }
  7281. }
  7282. static void close_conn(struct mg_connection *c) {
  7283. struct connstate *s = (struct connstate *) (c + 1);
  7284. mg_iobuf_free(&s->raw); // For TLS connections, release raw data
  7285. if (c->is_udp == false && c->is_listening == false) { // For TCP conns,
  7286. struct mg_tcpip_if *ifp =
  7287. (struct mg_tcpip_if *) c->mgr->priv; // send TCP FIN
  7288. tx_tcp(ifp, s->mac, c->rem.ip, TH_FIN | TH_ACK, c->loc.port, c->rem.port,
  7289. mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  7290. }
  7291. mg_close_conn(c);
  7292. }
  7293. static bool can_write(struct mg_connection *c) {
  7294. return c->is_connecting == 0 && c->is_resolving == 0 && c->send.len > 0 &&
  7295. c->is_tls_hs == 0 && c->is_arplooking == 0;
  7296. }
  7297. void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
  7298. struct mg_connection *c, *tmp;
  7299. uint64_t now = mg_millis();
  7300. mg_tcpip_poll((struct mg_tcpip_if *) mgr->priv, now);
  7301. mg_timer_poll(&mgr->timers, now);
  7302. for (c = mgr->conns; c != NULL; c = tmp) {
  7303. tmp = c->next;
  7304. mg_call(c, MG_EV_POLL, &now);
  7305. MG_VERBOSE(("%lu .. %c%c%c%c%c", c->id, c->is_tls ? 'T' : 't',
  7306. c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
  7307. c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
  7308. if (c->is_tls_hs) mg_tls_handshake(c);
  7309. if (can_write(c)) write_conn(c);
  7310. if (c->is_draining && c->send.len == 0) c->is_closing = 1;
  7311. if (c->is_closing) close_conn(c);
  7312. }
  7313. (void) ms;
  7314. }
  7315. bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
  7316. struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
  7317. bool res = false;
  7318. if (ifp->ip == 0 || ifp->state != MG_TCPIP_STATE_READY) {
  7319. mg_error(c, "net down");
  7320. } else if (c->is_udp) {
  7321. struct connstate *s = (struct connstate *) (c + 1);
  7322. tx_udp(ifp, s->mac, ifp->ip, c->loc.port, c->rem.ip, c->rem.port, buf, len);
  7323. res = true;
  7324. } else {
  7325. res = mg_iobuf_add(&c->send, c->send.len, buf, len);
  7326. }
  7327. return res;
  7328. }
  7329. #endif // MG_ENABLE_TCPIP