mongoose.c 127 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226
  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. // Copyright (c) 2013-2020 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.cesanta.com/license>.
  17. #include "mongoose.h"
  18. #ifdef MG_ENABLE_LINES
  19. #line 1 "src/private.h"
  20. #endif
  21. void mg_connect_resolved(struct mg_connection *);
  22. #if MG_ARCH == MG_ARCH_FREERTOS
  23. static inline void *mg_calloc(int cnt, size_t size) {
  24. void *p = pvPortMalloc(size);
  25. if (p != NULL) memset(p, 0, size);
  26. return p;
  27. }
  28. #define calloc(a, b) mg_calloc((a), (b))
  29. #define malloc(a) pvPortMalloc(a)
  30. #define free(a) vPortFree(a)
  31. #endif
  32. #ifdef MG_ENABLE_LINES
  33. #line 1 "src/base64.c"
  34. #endif
  35. #include <string.h>
  36. static int mg_b64idx(int c) {
  37. if (c < 26) {
  38. return c + 'A';
  39. } else if (c < 52) {
  40. return c - 26 + 'a';
  41. } else if (c < 62) {
  42. return c - 52 + '0';
  43. } else {
  44. return c == 62 ? '+' : '/';
  45. }
  46. }
  47. static int mg_b64rev(int c) {
  48. if (c >= 'A' && c <= 'Z') {
  49. return c - 'A';
  50. } else if (c >= 'a' && c <= 'z') {
  51. return c + 26 - 'a';
  52. } else if (c >= '0' && c <= '9') {
  53. return c + 52 - '0';
  54. } else if (c == '+') {
  55. return 62;
  56. } else if (c == '/') {
  57. return 63;
  58. } else if (c == '=') {
  59. return 64;
  60. } else {
  61. return -1;
  62. }
  63. }
  64. int mg_base64_update(unsigned char ch, char *to, int n) {
  65. unsigned char rem = (n & 3) % 3;
  66. if (rem == 0) {
  67. to[n] = mg_b64idx(ch >> 2);
  68. to[++n] = (ch & 3) << 4;
  69. } else if (rem == 1) {
  70. to[n] = mg_b64idx(to[n] | (ch >> 4));
  71. to[++n] = (ch & 15) << 2;
  72. } else {
  73. to[n] = mg_b64idx(to[n] | (ch >> 6));
  74. to[++n] = mg_b64idx(ch & 63);
  75. n++;
  76. }
  77. return n;
  78. }
  79. int mg_base64_final(char *to, int n) {
  80. int saved = n;
  81. // printf("---[%.*s]\n", n, to);
  82. if (n & 3) n = mg_base64_update(0, to, n);
  83. if ((saved & 3) == 2) n--;
  84. // printf(" %d[%.*s]\n", n, n, to);
  85. while (n & 3) to[n++] = '=';
  86. to[n] = '\0';
  87. return n;
  88. }
  89. int mg_base64_encode(const unsigned char *p, int n, char *to) {
  90. int i, len = 0;
  91. for (i = 0; i < n; i++) len = mg_base64_update(p[i], to, len);
  92. len = mg_base64_final(to, len);
  93. return len;
  94. }
  95. int mg_base64_decode(const char *src, int n, char *dst) {
  96. const char *end = src + n;
  97. int len = 0;
  98. while (src + 3 < end) {
  99. int a = mg_b64rev(src[0]), b = mg_b64rev(src[1]), c = mg_b64rev(src[2]),
  100. d = mg_b64rev(src[3]);
  101. if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) return 0;
  102. dst[len++] = (a << 2) | (b >> 4);
  103. if (src[2] != '=') {
  104. dst[len++] = (b << 4) | (c >> 2);
  105. if (src[3] != '=') dst[len++] = (c << 6) | d;
  106. }
  107. src += 4;
  108. }
  109. dst[len] = '\0';
  110. return len;
  111. }
  112. #ifdef MG_ENABLE_LINES
  113. #line 1 "src/dns.c"
  114. #endif
  115. struct dns_data {
  116. struct dns_data *next;
  117. struct mg_connection *c;
  118. unsigned long expire;
  119. uint16_t txnid;
  120. };
  121. static struct dns_data *s_reqs; // Active DNS requests
  122. static void mg_sendnsreq(struct mg_connection *, struct mg_str *, int,
  123. struct mg_dns *, bool);
  124. static void mg_dns_free(struct dns_data *d) {
  125. LIST_DELETE(struct dns_data, &s_reqs, d);
  126. free(d);
  127. }
  128. void mg_resolve_cancel(struct mg_connection *c) {
  129. struct dns_data *tmp, *d;
  130. for (d = s_reqs; d != NULL; d = tmp) {
  131. tmp = d->next;
  132. if (d->c == c) mg_dns_free(d);
  133. }
  134. }
  135. static size_t mg_dns_parse_name_depth(const uint8_t *s, size_t len, size_t ofs,
  136. char *to, size_t tolen, int depth) {
  137. size_t i = 0, j = 0;
  138. if (tolen > 0) to[0] = '\0';
  139. if (depth > 5) return 0;
  140. while (ofs + i + 1 < len) {
  141. size_t n = s[ofs + i];
  142. if (n == 0) {
  143. i++;
  144. break;
  145. }
  146. if (n & 0xc0) {
  147. size_t ptr = (((n & 0x3f) << 8) | s[ofs + i + 1]); // 12 is hdr len
  148. if (ptr + 1 < len && (s[ptr] & 0xc0) == 0 &&
  149. mg_dns_parse_name_depth(s, len, ptr, to, tolen, depth + 1) == 0)
  150. return 0;
  151. i += 2;
  152. break;
  153. }
  154. if (ofs + i + n + 1 >= len) return 0;
  155. if (j > 0) {
  156. if (j < tolen) to[j] = '.';
  157. j++;
  158. }
  159. if (j + n < tolen) memcpy(&to[j], &s[ofs + i + 1], n);
  160. j += n;
  161. i += n + 1;
  162. if (j < tolen) to[j] = '\0'; // Zero-terminate this chunk
  163. }
  164. if (tolen > 0) to[tolen - 1] = '\0'; // Make sure make sure it is nul-term
  165. return i;
  166. }
  167. size_t mg_dns_parse_name(const uint8_t *s, size_t n, size_t ofs, char *dst,
  168. size_t dstlen) {
  169. return mg_dns_parse_name_depth(s, n, ofs, dst, dstlen, 0);
  170. }
  171. size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
  172. bool is_question, struct mg_dns_rr *rr) {
  173. const struct mg_dns_header *h = (struct mg_dns_header *) buf;
  174. const uint8_t *s = buf + ofs, *e = &buf[len];
  175. memset(rr, 0, sizeof(*rr));
  176. if (len < sizeof(*h)) return 0; // Too small, headers dont fit
  177. if (len > 512) return 0; // Too large, we don't expect that
  178. if (s >= e) return 0; // Overflow
  179. if ((rr->nlen = (uint16_t) mg_dns_parse_name(buf, len, ofs, NULL, 0)) == 0)
  180. return 0;
  181. s += rr->nlen + 4;
  182. if (s > e) return 0;
  183. rr->atype = ((uint16_t) s[-4] << 8) | s[-3];
  184. rr->aclass = ((uint16_t) s[-2] << 8) | s[-1];
  185. if (is_question) return rr->nlen + 4;
  186. s += 6;
  187. if (s > e) return 0;
  188. rr->alen = ((uint16_t) s[-2] << 8) | s[-1];
  189. if (s + rr->alen > e) return 0;
  190. return rr->nlen + rr->alen + 10;
  191. }
  192. bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
  193. const struct mg_dns_header *h = (struct mg_dns_header *) buf;
  194. struct mg_dns_rr rr;
  195. size_t i, n, ofs = sizeof(*h);
  196. memset(dm, 0, sizeof(*dm));
  197. if (len < sizeof(*h)) return 0; // Too small, headers dont fit
  198. if (mg_ntohs(h->num_questions) > 1) return 0; // Sanity
  199. if (mg_ntohs(h->num_answers) > 10) return 0; // Sanity
  200. dm->txnid = mg_ntohs(h->txnid);
  201. for (i = 0; i < mg_ntohs(h->num_questions); i++) {
  202. if ((n = mg_dns_parse_rr(buf, len, ofs, true, &rr)) == 0) return false;
  203. // LOG(LL_INFO, ("Q %zu %zu", ofs, n));
  204. ofs += n;
  205. }
  206. for (i = 0; i < mg_ntohs(h->num_answers); i++) {
  207. // LOG(LL_INFO, ("A -- %zu %zu %s", ofs, n, dm->name));
  208. if ((n = mg_dns_parse_rr(buf, len, ofs, false, &rr)) == 0) return false;
  209. mg_dns_parse_name(buf, len, ofs, dm->name, sizeof(dm->name));
  210. ofs += n;
  211. if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) {
  212. dm->addr.is_ip6 = false;
  213. memcpy(&dm->addr.ip, &buf[ofs - 4], 4);
  214. dm->resolved = true;
  215. break; // Return success
  216. } else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) {
  217. dm->addr.is_ip6 = true;
  218. memcpy(&dm->addr.ip6, &buf[ofs - 16], 16);
  219. dm->resolved = true;
  220. break; // Return success
  221. }
  222. }
  223. return true;
  224. }
  225. static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
  226. void *fn_data) {
  227. struct dns_data *d, *tmp;
  228. if (ev == MG_EV_POLL) {
  229. unsigned long now = *(unsigned long *) ev_data;
  230. for (d = s_reqs; d != NULL; d = tmp) {
  231. tmp = d->next;
  232. // LOG(LL_DEBUG, ("%lu %lu dns poll", d->expire, now));
  233. if (now > d->expire) mg_error(d->c, "DNS timeout");
  234. }
  235. } else if (ev == MG_EV_READ) {
  236. struct mg_dns_message dm;
  237. int resolved = 0;
  238. if (mg_dns_parse(c->recv.buf, c->recv.len, &dm) == false) {
  239. char *s = mg_hexdump(c->recv.buf, c->recv.len);
  240. LOG(LL_ERROR, ("Unexpected DNS response:\n%s\n", s));
  241. free(s);
  242. } else {
  243. LOG(LL_VERBOSE_DEBUG, ("%s %d", dm.name, dm.resolved));
  244. for (d = s_reqs; d != NULL; d = tmp) {
  245. tmp = d->next;
  246. // LOG(LL_INFO, ("d %p %hu %hu", d, d->txnid, dm.txnid));
  247. if (dm.txnid != d->txnid) continue;
  248. if (d->c->is_resolving) {
  249. d->c->is_resolving = 0;
  250. if (dm.resolved) {
  251. #if MG_ENABLE_LOG
  252. char buf[100];
  253. #endif
  254. dm.addr.port = d->c->peer.port; // Save port
  255. d->c->peer = dm.addr; // Copy resolved address
  256. LOG(LL_DEBUG, ("%lu %s resolved to %s", d->c->id, dm.name,
  257. mg_ntoa(&d->c->peer, buf, sizeof(buf))));
  258. mg_connect_resolved(d->c);
  259. #if MG_ENABLE_IPV6
  260. } else if (dm.addr.is_ip6 == false && dm.name[0] != '\0') {
  261. struct mg_str x = mg_str(dm.name);
  262. mg_sendnsreq(d->c, &x, c->mgr->dnstimeout, &c->mgr->dns6, true);
  263. #endif
  264. } else {
  265. mg_error(d->c, "%s DNS lookup failed", dm.name);
  266. }
  267. } else {
  268. LOG(LL_ERROR, ("%lu already resolved", d->c->id));
  269. }
  270. mg_dns_free(d);
  271. resolved = 1;
  272. }
  273. }
  274. if (!resolved) LOG(LL_ERROR, ("stray DNS reply"));
  275. c->recv.len = 0;
  276. } else if (ev == MG_EV_CLOSE) {
  277. for (d = s_reqs; d != NULL; d = tmp) {
  278. tmp = d->next;
  279. mg_dns_free(d);
  280. }
  281. }
  282. (void) fn_data;
  283. }
  284. void mg_dns_send(struct mg_connection *c, const struct mg_str *name,
  285. uint16_t txnid, bool ipv6) {
  286. struct {
  287. struct mg_dns_header header;
  288. uint8_t data[256];
  289. } pkt;
  290. size_t i, n;
  291. memset(&pkt, 0, sizeof(pkt));
  292. pkt.header.txnid = mg_htons(txnid);
  293. pkt.header.flags = mg_htons(0x100);
  294. pkt.header.num_questions = mg_htons(1);
  295. for (i = n = 0; i < sizeof(pkt.data) - 5; i++) {
  296. if (name->ptr[i] == '.' || i >= name->len) {
  297. pkt.data[n] = (uint8_t)(i - n);
  298. memcpy(&pkt.data[n + 1], name->ptr + n, i - n);
  299. n = i + 1;
  300. }
  301. if (i >= name->len) break;
  302. }
  303. memcpy(&pkt.data[n], "\x00\x00\x01\x00\x01", 5); // A query
  304. n += 5;
  305. if (ipv6) pkt.data[n - 3] = 0x1c; // AAAA query
  306. // memcpy(&pkt.data[n], "\xc0\x0c\x00\x1c\x00\x01", 6); // AAAA query
  307. // n += 6;
  308. mg_send(c, &pkt, sizeof(pkt.header) + n);
  309. #if 0
  310. // Immediately after A query, send AAAA query. Whatever reply comes first,
  311. // we'll use it. Note: we cannot send two queries in a single packet.
  312. // https://stackoverflow.com/questions/4082081/requesting-a-and-aaaa-records-in-single-dns-query
  313. pkt.data[n - 3] = 0x1c; // AAAA query
  314. mg_send(c, &pkt, sizeof(pkt.header) + n);
  315. #endif
  316. }
  317. static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
  318. struct mg_dns *dnsc, bool ipv6) {
  319. struct dns_data *d = NULL;
  320. if (dnsc->url == NULL) {
  321. mg_error(c, "DNS server URL is NULL. Call mg_mgr_init()");
  322. } else if (dnsc->c == NULL) {
  323. dnsc->c = mg_connect(c->mgr, dnsc->url, NULL, NULL);
  324. if (dnsc->c != NULL) {
  325. dnsc->c->pfn = dns_cb;
  326. snprintf(dnsc->c->label, sizeof(dnsc->c->label), "%s", "DNS");
  327. // dnsc->c->is_hexdumping = 1;
  328. }
  329. }
  330. if (dnsc->c == NULL) {
  331. mg_error(c, "resolver");
  332. } else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) {
  333. mg_error(c, "resolve OOM");
  334. } else {
  335. d->txnid = s_reqs ? s_reqs->txnid + 1 : 1;
  336. d->next = s_reqs;
  337. s_reqs = d;
  338. d->expire = mg_millis() + ms;
  339. d->c = c;
  340. c->is_resolving = 1;
  341. LOG(LL_VERBOSE_DEBUG, ("%lu resolving %.*s, txnid %hu", c->id,
  342. (int) name->len, name->ptr, d->txnid));
  343. mg_dns_send(dnsc->c, name, d->txnid, ipv6);
  344. }
  345. }
  346. void mg_resolve(struct mg_connection *c, struct mg_str *name, int ms) {
  347. if (mg_aton(*name, &c->peer)) {
  348. // name is an IP address, do not fire name resolution
  349. mg_connect_resolved(c);
  350. } else {
  351. // name is not an IP, send DNS resolution request
  352. mg_sendnsreq(c, name, ms, &c->mgr->dns4, false);
  353. }
  354. }
  355. #ifdef MG_ENABLE_LINES
  356. #line 1 "src/event.c"
  357. #endif
  358. void mg_call(struct mg_connection *c, int ev, void *ev_data) {
  359. if (c->pfn != NULL) c->pfn(c, ev, ev_data, c->pfn_data);
  360. if (c->fn != NULL) c->fn(c, ev, ev_data, c->fn_data);
  361. }
  362. void mg_error(struct mg_connection *c, const char *fmt, ...) {
  363. char mem[256], *buf = mem;
  364. va_list ap;
  365. va_start(ap, fmt);
  366. mg_vasprintf(&buf, sizeof(mem), fmt, ap);
  367. va_end(ap);
  368. LOG(LL_ERROR, ("%lu %s", c->id, buf));
  369. mg_call(c, MG_EV_ERROR, buf);
  370. if (buf != mem) free(buf);
  371. c->is_closing = 1;
  372. }
  373. #ifdef MG_ENABLE_LINES
  374. #line 1 "src/http.c"
  375. #endif
  376. struct http_data {
  377. void *old_pfn_data; // Previous pfn_data
  378. FILE *fp; // For static file serving
  379. };
  380. // Multipart POST example:
  381. // https://gist.github.com/cpq/b8dd247571e6ee9c54ef7e8dfcfecf48
  382. void mg_http_bauth(struct mg_connection *c, const char *user,
  383. const char *pass) {
  384. struct mg_str u = mg_str(user), p = mg_str(pass);
  385. size_t need = c->send.len + 36 + (u.len + p.len) * 2;
  386. if (c->send.size < need) mg_iobuf_resize(&c->send, need);
  387. if (c->send.size >= need) {
  388. size_t i, n = 0;
  389. char *buf = (char *) &c->send.buf[c->send.len + 21];
  390. memcpy(&buf[-21], "Authorization: Basic ", 21); // DON'T use mg_send!
  391. for (i = 0; i < u.len; i++) n = mg_base64_update(u.ptr[i], buf, n);
  392. if (p.len > 0) {
  393. n = mg_base64_update(':', buf, n);
  394. for (i = 0; i < p.len; i++) n = mg_base64_update(p.ptr[i], buf, n);
  395. }
  396. n = mg_base64_final(buf, n);
  397. c->send.len += 21 + n + 2;
  398. memcpy(&c->send.buf[c->send.len - 2], "\r\n", 2);
  399. } else {
  400. LOG(LL_ERROR, ("%lu %s cannot resize iobuf %d->%d ", c->id, c->label,
  401. (int) c->send.size, (int) need));
  402. }
  403. }
  404. int mg_http_get_var(const struct mg_str *buf, const char *name, char *dst,
  405. int dst_len) {
  406. const char *p, *e, *s;
  407. size_t name_len;
  408. int len;
  409. if (dst == NULL || dst_len == 0) {
  410. len = -2; // Bad destination
  411. } else if (buf->ptr == NULL || name == NULL || buf->len == 0) {
  412. len = -1; // Bad source
  413. dst[0] = '\0';
  414. } else {
  415. name_len = strlen(name);
  416. e = buf->ptr + buf->len;
  417. len = -4; // Name does not exist
  418. dst[0] = '\0';
  419. for (p = buf->ptr; p + name_len < e; p++) {
  420. if ((p == buf->ptr || p[-1] == '&') && p[name_len] == '=' &&
  421. !mg_ncasecmp(name, p, name_len)) {
  422. p += name_len + 1;
  423. s = (const char *) memchr(p, '&', (size_t)(e - p));
  424. if (s == NULL) s = e;
  425. len = mg_url_decode(p, (size_t)(s - p), dst, dst_len, 1);
  426. if (len == -1) len = -3; // Failed to decode
  427. break;
  428. }
  429. }
  430. }
  431. return len;
  432. }
  433. int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len,
  434. int is_form_url_encoded) {
  435. size_t i, j;
  436. for (i = j = 0; i < src_len && j + 1 < dst_len; i++, j++) {
  437. if (src[i] == '%') {
  438. // Use `i + 2 < src_len`, not `i < src_len - 2`, note small src_len
  439. if (i + 2 < src_len && isxdigit(*(const unsigned char *) (src + i + 1)) &&
  440. isxdigit(*(const unsigned char *) (src + i + 2))) {
  441. mg_unhex(src + i + 1, 2, (uint8_t *) &dst[j]);
  442. i += 2;
  443. } else {
  444. return -1;
  445. }
  446. } else if (is_form_url_encoded && src[i] == '+') {
  447. dst[j] = ' ';
  448. } else {
  449. dst[j] = src[i];
  450. }
  451. }
  452. if (j < dst_len) dst[j] = '\0'; // Null-terminate the destination
  453. return i >= src_len ? (int) j : -1;
  454. }
  455. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len) {
  456. size_t i;
  457. for (i = 0; i < buf_len; i++) {
  458. if (!isprint(buf[i]) && buf[i] != '\r' && buf[i] != '\n' && buf[i] < 128)
  459. return -1;
  460. if ((i > 0 && buf[i] == '\n' && buf[i - 1] == '\n') ||
  461. (i > 3 && buf[i] == '\n' && buf[i - 1] == '\r' && buf[i - 2] == '\n'))
  462. return (int) i + 1;
  463. }
  464. return 0;
  465. }
  466. static const char *skip(const char *s, const char *end, const char *delims,
  467. struct mg_str *v) {
  468. v->ptr = s;
  469. while (s < end && strchr(delims, *(unsigned char *) s) == NULL) s++;
  470. v->len = s - v->ptr;
  471. while (s < end && strchr(delims, *(unsigned char *) s) != NULL) s++;
  472. return s;
  473. }
  474. struct mg_str *mg_http_get_header(struct mg_http_message *h, const char *name) {
  475. size_t i, n = strlen(name), max = sizeof(h->headers) / sizeof(h->headers[0]);
  476. for (i = 0; i < max && h->headers[i].name.len > 0; i++) {
  477. struct mg_str *k = &h->headers[i].name, *v = &h->headers[i].value;
  478. if (n == k->len && mg_ncasecmp(k->ptr, name, n) == 0) return v;
  479. }
  480. return NULL;
  481. }
  482. void mg_http_parse_headers(const char *s, const char *end,
  483. struct mg_http_header *h, int max_headers) {
  484. int i;
  485. for (i = 0; i < max_headers; i++) {
  486. struct mg_str k, v, tmp;
  487. const char *he = skip(s, end, "\n", &tmp);
  488. s = skip(s, he, ": \r\n", &k);
  489. s = skip(s, he, "\r\n", &v);
  490. if (k.len == tmp.len) continue;
  491. while (v.len > 0 && v.ptr[v.len - 1] == ' ') v.len--; // Trim spaces
  492. if (k.len == 0) break;
  493. // LOG(LL_INFO, ("--HH [%.*s] [%.*s] [%.*s]", (int) tmp.len - 1, tmp.ptr,
  494. //(int) k.len, k.ptr, (int) v.len, v.ptr));
  495. h[i].name = k;
  496. h[i].value = v;
  497. }
  498. }
  499. int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) {
  500. int is_response, req_len = mg_http_get_request_len((unsigned char *) s, len);
  501. const char *end = s + req_len, *qs;
  502. struct mg_str *cl;
  503. memset(hm, 0, sizeof(*hm));
  504. if (req_len <= 0) return req_len;
  505. hm->message.ptr = s;
  506. hm->body.ptr = s + req_len;
  507. hm->message.len = hm->body.len = (size_t) ~0; // Set body length to infinite
  508. // Parse request line
  509. s = skip(s, end, " ", &hm->method);
  510. s = skip(s, end, " ", &hm->uri);
  511. s = skip(s, end, "\r\n", &hm->proto);
  512. if (hm->uri.ptr <= hm->method.ptr || hm->proto.ptr <= hm->uri.ptr) return -1;
  513. // If URI contains '?' character, setup query string
  514. if ((qs = (const char *) memchr(hm->uri.ptr, '?', hm->uri.len)) != NULL) {
  515. hm->query.ptr = qs + 1;
  516. hm->query.len = &hm->uri.ptr[hm->uri.len] - (qs + 1);
  517. hm->uri.len = qs - hm->uri.ptr;
  518. }
  519. mg_http_parse_headers(s, end, hm->headers,
  520. sizeof(hm->headers) / sizeof(hm->headers[0]));
  521. if ((cl = mg_http_get_header(hm, "Content-Length")) != NULL) {
  522. hm->body.len = (size_t) mg_to64(*cl);
  523. hm->message.len = req_len + hm->body.len;
  524. }
  525. // mg_http_parse() is used to parse both HTTP requests and HTTP
  526. // responses. If HTTP response does not have Content-Length set, then
  527. // body is read until socket is closed, i.e. body.len is infinite (~0).
  528. //
  529. // For HTTP requests though, according to
  530. // http://tools.ietf.org/html/rfc7231#section-8.1.3,
  531. // only POST and PUT methods have defined body semantics.
  532. // Therefore, if Content-Length is not specified and methods are
  533. // not one of PUT or POST, set body length to 0.
  534. //
  535. // So, if it is HTTP request, and Content-Length is not set,
  536. // and method is not (PUT or POST) then reset body length to zero.
  537. is_response = mg_ncasecmp(hm->method.ptr, "HTTP/", 5) == 0;
  538. if (hm->body.len == (size_t) ~0 && !is_response &&
  539. mg_vcasecmp(&hm->method, "PUT") != 0 &&
  540. mg_vcasecmp(&hm->method, "POST") != 0) {
  541. hm->body.len = 0;
  542. hm->message.len = req_len;
  543. }
  544. // The 204 (No content) responses also have 0 body length
  545. if (hm->body.len == (size_t) ~0 && is_response &&
  546. mg_vcasecmp(&hm->uri, "204") == 0) {
  547. hm->body.len = 0;
  548. hm->message.len = req_len;
  549. }
  550. return req_len;
  551. }
  552. static void mg_http_vprintf_chunk(struct mg_connection *c, const char *fmt,
  553. va_list ap) {
  554. char mem[256], *buf = mem;
  555. int len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
  556. mg_printf(c, "%X\r\n", len);
  557. mg_send(c, buf, len);
  558. mg_send(c, "\r\n", 2);
  559. if (buf != mem) free(buf);
  560. }
  561. void mg_http_printf_chunk(struct mg_connection *c, const char *fmt, ...) {
  562. va_list ap;
  563. va_start(ap, fmt);
  564. mg_http_vprintf_chunk(c, fmt, ap);
  565. va_end(ap);
  566. }
  567. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len) {
  568. mg_printf(c, "%X\r\n", len);
  569. mg_send(c, buf, len);
  570. mg_send(c, "\r\n", 2);
  571. }
  572. void mg_http_reply(struct mg_connection *c, int code, const char *headers,
  573. const char *fmt, ...) {
  574. char mem[100], *buf = mem;
  575. va_list ap;
  576. int len;
  577. va_start(ap, fmt);
  578. len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
  579. va_end(ap);
  580. mg_printf(c, "HTTP/1.1 %d OK\r\n%sContent-Length: %d\r\n\r\n", code,
  581. headers == NULL ? "" : headers, len);
  582. mg_send(c, buf, len);
  583. if (buf != mem) free(buf);
  584. }
  585. #if MG_ENABLE_FS
  586. static void http_cb(struct mg_connection *, int, void *, void *);
  587. static void restore_http_cb(struct mg_connection *c) {
  588. struct http_data *d = (struct http_data *) c->pfn_data;
  589. if (d->fp != NULL) fclose(d->fp);
  590. c->pfn_data = d->old_pfn_data;
  591. c->pfn = http_cb;
  592. free(d);
  593. }
  594. char *mg_http_etag(char *buf, size_t len, mg_stat_t *st) {
  595. snprintf(buf, len, "\"%lx." MG_INT64_FMT "\"", (unsigned long) st->st_mtime,
  596. (int64_t) st->st_size);
  597. return buf;
  598. }
  599. int mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
  600. const char *dir) {
  601. char offset[40] = "", name[200] = "", path[256];
  602. mg_http_get_var(&hm->query, "offset", offset, sizeof(offset));
  603. mg_http_get_var(&hm->query, "name", name, sizeof(name));
  604. if (name[0] == '\0') {
  605. mg_http_reply(c, 400, "", "%s", "name required");
  606. return -1;
  607. } else {
  608. FILE *fp;
  609. size_t oft = strtoul(offset, NULL, 0);
  610. snprintf(path, sizeof(path), "%s%c%s", dir, MG_DIRSEP, name);
  611. LOG(LL_DEBUG,
  612. ("%p %d bytes @ %d [%s]", c->fd, (int) hm->body.len, (int) oft, name));
  613. if ((fp = fopen(path, oft == 0 ? "wb" : "a")) == NULL) {
  614. mg_http_reply(c, 400, "", "fopen(%s): %d", name, errno);
  615. return -2;
  616. } else {
  617. fwrite(hm->body.ptr, 1, hm->body.len, fp);
  618. fclose(fp);
  619. mg_http_reply(c, 200, "", "");
  620. return hm->body.len;
  621. }
  622. }
  623. }
  624. static void static_cb(struct mg_connection *c, int ev, void *ev_data,
  625. void *fn_data) {
  626. if (ev == MG_EV_WRITE || ev == MG_EV_POLL) {
  627. struct http_data *d = (struct http_data *) fn_data;
  628. // Read to send IO buffer directly, avoid extra on-stack buffer
  629. size_t n, max = 2 * MG_IO_SIZE;
  630. if (c->send.size < max) mg_iobuf_resize(&c->send, max);
  631. if (c->send.len >= c->send.size) return; // Rate limit
  632. n = fread(c->send.buf + c->send.len, 1, c->send.size - c->send.len, d->fp);
  633. if (n > 0) c->send.len += n;
  634. if (c->send.len < c->send.size) restore_http_cb(c);
  635. } else if (ev == MG_EV_CLOSE) {
  636. restore_http_cb(c);
  637. }
  638. (void) ev_data;
  639. }
  640. static const char *guess_content_type(const char *filename) {
  641. size_t n = strlen(filename);
  642. #define MIME_ENTRY(_ext, _type) \
  643. { _ext, sizeof(_ext) - 1, _type }
  644. const struct {
  645. const char *ext;
  646. size_t ext_len;
  647. const char *type;
  648. } * t, types[] = {
  649. MIME_ENTRY("html", "text/html"),
  650. MIME_ENTRY("htm", "text/html"),
  651. MIME_ENTRY("shtml", "text/html"),
  652. MIME_ENTRY("css", "text/css"),
  653. MIME_ENTRY("js", "text/javascript"),
  654. MIME_ENTRY("mjs", "text/javascript"),
  655. MIME_ENTRY("json", "application/json"),
  656. MIME_ENTRY("ico", "image/x-icon"),
  657. MIME_ENTRY("gif", "image/gif"),
  658. MIME_ENTRY("jpg", "image/jpeg"),
  659. MIME_ENTRY("jpeg", "image/jpeg"),
  660. MIME_ENTRY("png", "image/png"),
  661. MIME_ENTRY("svg", "image/svg+xml"),
  662. MIME_ENTRY("txt", "text/plain"),
  663. MIME_ENTRY("wav", "audio/wav"),
  664. MIME_ENTRY("mp3", "audio/mpeg"),
  665. MIME_ENTRY("mid", "audio/mid"),
  666. MIME_ENTRY("ogg", "application/ogg"),
  667. MIME_ENTRY("xml", "application/xml"),
  668. MIME_ENTRY("ttf", "font/ttf"),
  669. MIME_ENTRY("json", "application/json"),
  670. MIME_ENTRY("xsl", "application/xml"),
  671. MIME_ENTRY("doc", "application/msword"),
  672. MIME_ENTRY("exe", "application/octet-stream"),
  673. MIME_ENTRY("zip", "application/zip"),
  674. MIME_ENTRY("xls", "application/excel"),
  675. MIME_ENTRY("tgz", "application/tar-gz"),
  676. MIME_ENTRY("tar", "application/tar"),
  677. MIME_ENTRY("gz", "application/gzip"),
  678. MIME_ENTRY("rar", "application/rar"),
  679. MIME_ENTRY("rtf", "application/rtf"),
  680. MIME_ENTRY("pdf", "application/pdf"),
  681. MIME_ENTRY("mpg", "video/mpeg"),
  682. MIME_ENTRY("webm", "video/webm"),
  683. MIME_ENTRY("mpeg", "video/mpeg"),
  684. MIME_ENTRY("mov", "video/quicktime"),
  685. MIME_ENTRY("mp4", "video/mp4"),
  686. MIME_ENTRY("avi", "video/x-msvideo"),
  687. MIME_ENTRY("csv", "text/csv"),
  688. MIME_ENTRY("bmp", "image/bmp"),
  689. MIME_ENTRY("bin", "application/octet-stream"),
  690. MIME_ENTRY("wasm", "application/wasm"),
  691. {NULL, 0, NULL},
  692. };
  693. for (t = types; t->ext != NULL; t++) {
  694. if (n < t->ext_len + 2) continue;
  695. if (mg_ncasecmp(t->ext, &filename[n - t->ext_len], t->ext_len)) continue;
  696. return t->type;
  697. }
  698. return "text/plain";
  699. }
  700. void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
  701. const char *path, const char *mime, const char *hdrs) {
  702. struct mg_str *inm = mg_http_get_header(hm, "If-None-Match");
  703. mg_stat_t st;
  704. FILE *fp = fopen(path, "rb");
  705. char etag[64];
  706. if (fp == NULL || mg_stat(path, &st) != 0 ||
  707. mg_http_etag(etag, sizeof(etag), &st) != etag) {
  708. mg_http_reply(c, 404, "", "%s", "Not found\n");
  709. } else if (inm != NULL && mg_vcasecmp(inm, etag) == 0) {
  710. fclose(fp);
  711. mg_printf(c, "HTTP/1.1 304 Not Modified\r\nContent-Length: 0\r\n\r\n");
  712. } else {
  713. mg_printf(c,
  714. "HTTP/1.1 200 OK\r\nContent-Type: %s\r\n"
  715. "Etag: %s\r\nContent-Length: " MG_INT64_FMT "\r\n%s\r\n",
  716. mime, etag, (int64_t) st.st_size, hdrs ? hdrs : "");
  717. if (mg_vcasecmp(&hm->method, "HEAD") == 0) {
  718. fclose(fp);
  719. } else {
  720. struct http_data *d = (struct http_data *) calloc(1, sizeof(*d));
  721. if (d == NULL) {
  722. mg_error(c, "static HTTP OOM");
  723. } else {
  724. d->fp = fp;
  725. d->old_pfn_data = c->pfn_data;
  726. c->pfn = static_cb;
  727. c->pfn_data = d;
  728. }
  729. }
  730. }
  731. }
  732. #if MG_ARCH == MG_ARCH_ESP32 || MG_ARCH == MG_ARCH_ESP8266 || \
  733. MG_ARCH == MG_ARCH_FREERTOS
  734. char *realpath(const char *src, char *dst) {
  735. int len = strlen(src);
  736. if (len > PATH_MAX - 1) len = PATH_MAX - 1;
  737. strncpy(dst, src, len);
  738. dst[len] = '\0';
  739. return dst;
  740. }
  741. #endif
  742. // Try to avoid dirent API
  743. static int mg_is_dir(const char *path) {
  744. #if MG_ARCH == MG_ARCH_FREERTOS
  745. struct FF_STAT st;
  746. return (ff_stat(path, &st) == 0) && (st.st_mode & FF_IFDIR);
  747. #else
  748. struct stat st;
  749. return (stat(path, &st) == 0) && (st.st_mode & S_IFDIR);
  750. #endif
  751. }
  752. #if MG_ENABLE_DIRECTORY_LISTING
  753. #ifdef _WIN32
  754. struct dirent {
  755. char d_name[MAX_PATH];
  756. };
  757. typedef struct win32_dir {
  758. HANDLE handle;
  759. WIN32_FIND_DATAW info;
  760. struct dirent result;
  761. } DIR;
  762. int gettimeofday(struct timeval *tv, void *tz) {
  763. FILETIME ft;
  764. unsigned __int64 tmpres = 0;
  765. if (tv != NULL) {
  766. GetSystemTimeAsFileTime(&ft);
  767. tmpres |= ft.dwHighDateTime;
  768. tmpres <<= 32;
  769. tmpres |= ft.dwLowDateTime;
  770. tmpres /= 10; // convert into microseconds
  771. tmpres -= (int64_t) 11644473600000000;
  772. tv->tv_sec = (long) (tmpres / 1000000UL);
  773. tv->tv_usec = (long) (tmpres % 1000000UL);
  774. }
  775. (void) tz;
  776. return 0;
  777. }
  778. static int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
  779. int ret;
  780. char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
  781. strncpy(buf, path, sizeof(buf));
  782. buf[sizeof(buf) - 1] = '\0';
  783. // Trim trailing slashes. Leave backslash for paths like "X:\"
  784. p = buf + strlen(buf) - 1;
  785. while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
  786. memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
  787. ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
  788. // Convert back to Unicode. If doubly-converted string does not match the
  789. // original, something is fishy, reject.
  790. WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
  791. NULL, NULL);
  792. if (strcmp(buf, buf2) != 0) {
  793. wbuf[0] = L'\0';
  794. ret = 0;
  795. }
  796. return ret;
  797. }
  798. DIR *opendir(const char *name) {
  799. DIR *d = NULL;
  800. wchar_t wpath[MAX_PATH];
  801. DWORD attrs;
  802. if (name == NULL) {
  803. SetLastError(ERROR_BAD_ARGUMENTS);
  804. } else if ((d = (DIR *) malloc(sizeof(*d))) == NULL) {
  805. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  806. } else {
  807. to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0]));
  808. attrs = GetFileAttributesW(wpath);
  809. if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
  810. (void) wcscat(wpath, L"\\*");
  811. d->handle = FindFirstFileW(wpath, &d->info);
  812. d->result.d_name[0] = '\0';
  813. } else {
  814. free(d);
  815. d = NULL;
  816. }
  817. }
  818. return d;
  819. }
  820. int closedir(DIR *d) {
  821. int result = 0;
  822. if (d != NULL) {
  823. if (d->handle != INVALID_HANDLE_VALUE)
  824. result = FindClose(d->handle) ? 0 : -1;
  825. free(d);
  826. } else {
  827. result = -1;
  828. SetLastError(ERROR_BAD_ARGUMENTS);
  829. }
  830. return result;
  831. }
  832. struct dirent *readdir(DIR *d) {
  833. struct dirent *result = NULL;
  834. if (d != NULL) {
  835. memset(&d->result, 0, sizeof(d->result));
  836. if (d->handle != INVALID_HANDLE_VALUE) {
  837. result = &d->result;
  838. WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name,
  839. sizeof(result->d_name), NULL, NULL);
  840. if (!FindNextFileW(d->handle, &d->info)) {
  841. FindClose(d->handle);
  842. d->handle = INVALID_HANDLE_VALUE;
  843. }
  844. } else {
  845. SetLastError(ERROR_FILE_NOT_FOUND);
  846. }
  847. } else {
  848. SetLastError(ERROR_BAD_ARGUMENTS);
  849. }
  850. return result;
  851. }
  852. #endif
  853. static void printdirentry(struct mg_connection *c, struct mg_http_message *hm,
  854. const char *name, mg_stat_t *stp) {
  855. char size[64], mod[64]; //, path[PATH_MAX];
  856. int is_dir = S_ISDIR(stp->st_mode);
  857. const char *slash = is_dir ? "/" : "";
  858. if (is_dir) {
  859. snprintf(size, sizeof(size), "%s", "[DIR]");
  860. } else {
  861. if (stp->st_size < 1024) {
  862. snprintf(size, sizeof(size), "%d", (int) stp->st_size);
  863. } else if (stp->st_size < 0x100000) {
  864. snprintf(size, sizeof(size), "%.1fk", (double) stp->st_size / 1024.0);
  865. } else if (stp->st_size < 0x40000000) {
  866. snprintf(size, sizeof(size), "%.1fM", (double) stp->st_size / 1048576);
  867. } else {
  868. snprintf(size, sizeof(size), "%.1fG", (double) stp->st_size / 1073741824);
  869. }
  870. }
  871. strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", localtime(&stp->st_mtime));
  872. // mg_escape(file_name, path, sizeof(path));
  873. // href = mg_url_encode(mg_mk_str(file_name));
  874. mg_http_printf_chunk(c,
  875. " <tr><td><a href=\"%.*s%s%s\">%s%s</a></td>"
  876. "<td>%s</td><td>%s</td></tr>\n",
  877. (int) hm->uri.len, hm->uri.ptr, name, slash, name, slash,
  878. mod, size);
  879. // free((void *) href.p);
  880. }
  881. static void listdir(struct mg_connection *c, struct mg_http_message *hm,
  882. char *dir) {
  883. char path[PATH_MAX + 1], *p = &dir[strlen(dir) - 1];
  884. struct dirent *dp;
  885. DIR *dirp;
  886. while (p > dir && *p != '/') *p-- = '\0';
  887. if ((dirp = (opendir(dir))) != NULL) {
  888. mg_printf(c, "%s\r\n", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n");
  889. mg_http_printf_chunk(
  890. c,
  891. "<!DOCTYPE html><html><head><title>Index of %.*s</title>"
  892. "<style>th,td {text-align: left; padding-right: 1em; "
  893. "font-family: monospace; }</style></head>"
  894. "<body><h1>Index of %.*s</h1><table cellpadding=\"0\"><thead>"
  895. "<tr><th>Name</th><th>Modified</th><th>Size</th></tr>"
  896. "<tr><td colspan=\"3\"><hr></td></tr></thead><tbody>\n",
  897. (int) hm->uri.len, hm->uri.ptr, (int) hm->uri.len, hm->uri.ptr);
  898. while ((dp = readdir(dirp)) != NULL) {
  899. mg_stat_t st;
  900. // Do not show current dir and hidden files
  901. if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
  902. snprintf(path, sizeof(path), "%s/%s", dir, dp->d_name);
  903. if (mg_stat(path, &st) != 0) {
  904. LOG(LL_ERROR, ("%lu stat(%s): %d", c->id, path, errno));
  905. continue;
  906. }
  907. printdirentry(c, hm, dp->d_name, &st);
  908. }
  909. closedir(dirp);
  910. mg_http_printf_chunk(
  911. c,
  912. "</tbody><tfoot><tr><td colspan=\"3\"><hr></td></tr></tfoot>"
  913. "</table><address>Mongoose v.%s</address></body></html>\n",
  914. MG_VERSION);
  915. mg_http_write_chunk(c, "", 0);
  916. } else {
  917. mg_http_reply(c, 400, "", "Cannot open dir");
  918. LOG(LL_DEBUG, ("%lu opendir(%s) -> %d", c->id, dir, errno));
  919. }
  920. }
  921. #endif
  922. void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
  923. struct mg_http_serve_opts *opts) {
  924. char path[PATH_MAX + 2], root[sizeof(path) - 2], real[sizeof(path) - 2];
  925. path[0] = root[0] = real[0] = '\0';
  926. if (realpath(opts->root_dir, root) == NULL)
  927. LOG(LL_DEBUG, ("realpath(%s): %d", opts->root_dir, errno));
  928. if (!mg_is_dir(root)) {
  929. mg_http_reply(c, 400, "", "Bad web root [%s]\n", root);
  930. } else {
  931. char dec[PATH_MAX];
  932. // NOTE(lsm): Xilinx snprintf does not 0-terminate the detination for
  933. // the %.*s specifier, if the length is zero. Make sure hm->uri.len > 0
  934. bool is_index = false;
  935. int ndec = mg_url_decode(hm->uri.ptr, hm->uri.len, dec, sizeof(dec), 0);
  936. size_t n =
  937. snprintf(path, sizeof(path), "%s%.*s", root, ndec < 0 ? 0 : ndec, dec);
  938. while (n > 0 && n < sizeof(path) && path[n - 1] == '/') path[--n] = 0;
  939. if (realpath(path, real) == NULL)
  940. LOG(LL_DEBUG, ("realpath(%s): %d", path, errno));
  941. // LOG(LL_INFO, ("[%s] [%s] [%s] [%s]", dir, root, path, real));
  942. if (mg_is_dir(real)) {
  943. strncat(real, "/index.html", sizeof(real) - strlen(real) - 1);
  944. real[sizeof(real) - 1] = '\0';
  945. is_index = true;
  946. }
  947. if (strlen(real) < strlen(root) || memcmp(real, root, strlen(root)) != 0) {
  948. mg_http_reply(c, 404, "", "Not found %.*s\n", hm->uri.len, hm->uri.ptr);
  949. } else {
  950. FILE *fp = fopen(real, "r");
  951. #if MG_ENABLE_SSI
  952. if (is_index && fp == NULL) {
  953. char *p = real + strlen(real);
  954. while (p > real && p[-1] != '/') p--;
  955. strncpy(p, "index.shtml", &real[sizeof(real)] - p - 2);
  956. real[sizeof(real) - 1] = '\0';
  957. fp = fopen(real, "r");
  958. }
  959. #endif
  960. #if MG_ENABLE_HTTP_DEBUG_ENDPOINT
  961. snprintf(c->label, sizeof(c->label) - 1, "<-F %s", real);
  962. #endif
  963. if (is_index && fp == NULL) {
  964. #if MG_ENABLE_DIRECTORY_LISTING
  965. listdir(c, hm, real);
  966. #else
  967. mg_http_reply(c, 403, "", "%s", "Directory listing not supported");
  968. #endif
  969. #if MG_ENABLE_SSI
  970. } else if (opts->ssi_pattern != NULL &&
  971. mg_globmatch(opts->ssi_pattern, strlen(opts->ssi_pattern),
  972. real, strlen(real))) {
  973. mg_http_serve_ssi(c, root, real);
  974. #endif
  975. } else {
  976. mg_http_serve_file(c, hm, real, guess_content_type(real), NULL);
  977. }
  978. if (fp != NULL) fclose(fp);
  979. }
  980. }
  981. }
  982. #endif
  983. void mg_http_creds(struct mg_http_message *hm, char *user, int userlen,
  984. char *pass, int passlen) {
  985. struct mg_str *v = mg_http_get_header(hm, "Authorization");
  986. user[0] = pass[0] = '\0';
  987. if (v != NULL && v->len > 6 && memcmp(v->ptr, "Basic ", 6) == 0) {
  988. char buf[256];
  989. int n = mg_base64_decode(v->ptr + 6, (int) v->len - 6, buf);
  990. const char *p = (const char *) memchr(buf, ':', n);
  991. if (p != NULL) {
  992. snprintf(user, userlen, "%.*s", (int) (p - buf), buf);
  993. snprintf(pass, passlen, "%.*s", n - (int) (p - buf) - 1, p + 1);
  994. }
  995. } else if (v != NULL && v->len > 7 && memcmp(v->ptr, "Bearer ", 7) == 0) {
  996. snprintf(pass, passlen, "%.*s", (int) v->len - 7, v->ptr + 7);
  997. } else if ((v = mg_http_get_header(hm, "Cookie")) != NULL) {
  998. size_t i;
  999. for (i = 0; i < v->len - 13; i++) {
  1000. if (memcmp(&v->ptr[i], "access_token=", 13) == 0) {
  1001. const char *p2 = v->ptr + i + 13, *p3 = p2;
  1002. while (p2 < &v->ptr[v->len] && p2[0] != ';' && p2[0] != ' ') p2++;
  1003. snprintf(pass, passlen, "%.*s", (int) (p2 - p3), p3);
  1004. break;
  1005. }
  1006. }
  1007. } else {
  1008. mg_http_get_var(&hm->query, "access_token", pass, passlen);
  1009. }
  1010. }
  1011. bool mg_http_match_uri(const struct mg_http_message *hm, const char *glob) {
  1012. return mg_globmatch(glob, strlen(glob), hm->uri.ptr, hm->uri.len);
  1013. }
  1014. static void http_cb(struct mg_connection *c, int ev, void *ev_data,
  1015. void *fn_data) {
  1016. if (ev == MG_EV_READ || ev == MG_EV_CLOSE) {
  1017. struct mg_http_message hm;
  1018. for (;;) {
  1019. int n = mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
  1020. if (ev == MG_EV_CLOSE) {
  1021. hm.message.len = c->recv.len;
  1022. hm.body.len = hm.message.len - (hm.body.ptr - hm.message.ptr);
  1023. }
  1024. if (n < 0 && ev == MG_EV_READ) {
  1025. LOG(LL_ERROR, ("%lu HTTP parse error", c->id));
  1026. c->is_closing = 1;
  1027. break;
  1028. } else if (n > 0 && (size_t) c->recv.len >= hm.message.len) {
  1029. #if MG_ENABLE_HTTP_DEBUG_ENDPOINT
  1030. snprintf(c->label, sizeof(c->label) - 1, "<-[%.*s]", (int) hm.uri.len,
  1031. hm.uri.ptr);
  1032. if (mg_http_match_uri(&hm, "/debug/info")) {
  1033. struct mg_mgr *mgr = (struct mg_mgr *) fn_data;
  1034. struct mg_connection *x;
  1035. mg_printf(c, "%s\r\n",
  1036. "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n");
  1037. for (x = mgr->conns; x != NULL; x = x->next) {
  1038. // LOG(LL_INFO, ("%p %s", x->fd, x->label));
  1039. mg_http_printf_chunk(
  1040. c,
  1041. "%-4p %-12s %04d.%04d/%04d.%04d"
  1042. " %d%d%d%d%d%d%d%d%d%d%d%d%d%d\n",
  1043. x->fd, x->label, x->recv.len, x->recv.size, x->send.len,
  1044. x->send.size, c->is_listening, c->is_client, c->is_accepted,
  1045. c->is_resolving, c->is_connecting, c->is_tls, c->is_tls_hs,
  1046. c->is_udp, c->is_websocket, c->is_hexdumping, c->is_draining,
  1047. c->is_closing, c->is_readable, c->is_writable);
  1048. }
  1049. mg_http_write_chunk(c, "", 0);
  1050. mg_iobuf_delete(&c->recv, hm.message.len);
  1051. continue;
  1052. }
  1053. #endif
  1054. mg_call(c, MG_EV_HTTP_MSG, &hm);
  1055. mg_iobuf_delete(&c->recv, hm.message.len);
  1056. } else {
  1057. break;
  1058. }
  1059. }
  1060. }
  1061. (void) fn_data;
  1062. (void) ev_data;
  1063. }
  1064. struct mg_connection *mg_http_connect(struct mg_mgr *mgr, const char *url,
  1065. mg_event_handler_t fn, void *fn_data) {
  1066. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  1067. if (c != NULL) c->pfn = http_cb, c->pfn_data = mgr;
  1068. #if MG_ENABLE_HTTP_DEBUG_ENDPOINT
  1069. snprintf(c->label, sizeof(c->label) - 1, "->%s", url);
  1070. #endif
  1071. return c;
  1072. }
  1073. struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url,
  1074. mg_event_handler_t fn, void *fn_data) {
  1075. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  1076. if (c != NULL) c->pfn = http_cb, c->pfn_data = mgr;
  1077. #if MG_ENABLE_HTTP_DEBUG_ENDPOINT
  1078. if (c != NULL) snprintf(c->label, sizeof(c->label) - 1, "<-LSN");
  1079. #endif
  1080. return c;
  1081. }
  1082. #ifdef MG_ENABLE_LINES
  1083. #line 1 "src/iobuf.c"
  1084. #endif
  1085. #include <string.h>
  1086. int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
  1087. int ok = 1;
  1088. if (new_size == 0) {
  1089. free(io->buf);
  1090. io->buf = NULL;
  1091. io->len = io->size = 0;
  1092. } else if (new_size != io->size) {
  1093. // NOTE(lsm): do not use realloc here. Use malloc/free only, to ease the
  1094. // porting to some obscure platforms like FreeRTOS
  1095. void *p = malloc(new_size);
  1096. if (p != NULL) {
  1097. memcpy(p, io->buf, io->size < new_size ? io->size : new_size);
  1098. free(io->buf);
  1099. io->buf = (unsigned char *) p;
  1100. io->size = new_size;
  1101. } else {
  1102. ok = 0;
  1103. LOG(LL_ERROR,
  1104. ("%lu->%lu", (unsigned long) io->size, (unsigned long) new_size));
  1105. }
  1106. }
  1107. return ok;
  1108. }
  1109. int mg_iobuf_init(struct mg_iobuf *io, size_t size) {
  1110. int ok = 1;
  1111. io->buf = NULL;
  1112. io->len = io->size = 0;
  1113. if (size > 0) ok = mg_iobuf_resize(io, size);
  1114. return ok;
  1115. }
  1116. size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
  1117. size_t chunk_size) {
  1118. size_t new_size = io->len + len + chunk_size;
  1119. new_size -= new_size % chunk_size;
  1120. if (new_size != io->size) mg_iobuf_resize(io, new_size);
  1121. if (new_size != io->size) len = 0; // Realloc failure, append nothing
  1122. if (buf != NULL) memmove(io->buf + io->len, buf, len);
  1123. io->len += len;
  1124. return len;
  1125. }
  1126. size_t mg_iobuf_delete(struct mg_iobuf *io, size_t len) {
  1127. if (len > io->len) len = 0;
  1128. memmove(io->buf, io->buf + len, io->len - len);
  1129. io->len -= len;
  1130. return len;
  1131. }
  1132. void mg_iobuf_free(struct mg_iobuf *io) {
  1133. free(io->buf);
  1134. mg_iobuf_init(io, 0);
  1135. }
  1136. #ifdef MG_ENABLE_LINES
  1137. #line 1 "src/log.c"
  1138. #endif
  1139. #if MG_ENABLE_MGOS
  1140. #else
  1141. #if MG_ENABLE_LOG
  1142. static void mg_log_stdout(const void *buf, int len, void *userdata) {
  1143. (void) userdata;
  1144. fwrite(buf, 1, len, stdout);
  1145. fflush(stdout);
  1146. }
  1147. static const char *s_spec = "2";
  1148. static void (*s_fn)(const void *, int, void *) = mg_log_stdout;
  1149. static void *s_fn_param = NULL;
  1150. void mg_log_set(const char *spec) {
  1151. LOG(LL_DEBUG, ("Setting log level to %s", spec));
  1152. s_spec = spec;
  1153. }
  1154. bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
  1155. // static unsigned long seq;
  1156. int max = LL_INFO;
  1157. struct mg_str k, v, s = mg_str(s_spec);
  1158. const char *p = strrchr(file, '/');
  1159. p = p == NULL ? file : p + 1;
  1160. if (s_fn == NULL) return false;
  1161. while (mg_next_comma_entry(&s, &k, &v)) {
  1162. if (v.len == 0) max = atoi(k.ptr);
  1163. if (v.len > 0 && strncmp(p, k.ptr, k.len) == 0) max = atoi(v.ptr);
  1164. }
  1165. if (level <= max) {
  1166. char timebuf[21], buf[50] = "";
  1167. time_t t = time(NULL);
  1168. struct tm *tm = gmtime(&t);
  1169. int n, tag;
  1170. strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
  1171. tag = level == LL_ERROR ? 'E' : level == LL_INFO ? 'I' : ' ';
  1172. n = snprintf(buf, sizeof(buf), "%s %c %s:%d:%s", timebuf, tag, p, line,
  1173. fname);
  1174. if (n < 0 || n > (int) sizeof(buf) - 2) n = sizeof(buf) - 2;
  1175. while (n < (int) sizeof(buf) - 1) buf[n++] = ' ';
  1176. s_fn(buf, sizeof(buf) - 1, s_fn_param);
  1177. return true;
  1178. } else {
  1179. return false;
  1180. }
  1181. }
  1182. void mg_log(const char *fmt, ...) {
  1183. char mem[256], *buf = mem;
  1184. va_list ap;
  1185. int len = 0;
  1186. va_start(ap, fmt);
  1187. len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
  1188. va_end(ap);
  1189. s_fn(buf, len, s_fn_param);
  1190. s_fn("\n", 1, s_fn_param);
  1191. if (buf != mem) free(buf);
  1192. }
  1193. void mg_log_set_callback(void (*fn)(const void *, int, void *), void *param) {
  1194. s_fn = fn;
  1195. s_fn_param = param;
  1196. }
  1197. #endif
  1198. #endif
  1199. #ifdef MG_ENABLE_LINES
  1200. #line 1 "src/lwip.c"
  1201. #endif
  1202. #if MG_ENABLE_LWIP
  1203. #include <lwip/tcp.h>
  1204. #include <lwip/udp.h>
  1205. static void tcp_error_cb(void *arg, err_t err) {
  1206. struct mg_connection *c = (struct mg_connection *) arg;
  1207. mg_error(c, "%p err %ld", c->fd, err);
  1208. }
  1209. static err_t connect_cb(void *arg, struct tcp_pcb *pcb, err_t err) {
  1210. struct mg_connection *c = (struct mg_connection *) arg;
  1211. LOG(LL_DEBUG, ("err %ld, arg %p, pcb %p", err, arg, pcb));
  1212. c->is_connecting = 0;
  1213. if (err != ERR_OK) mg_error(c, "%p err %d", c->fd, err);
  1214. return err;
  1215. }
  1216. static err_t tcp_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p,
  1217. err_t err) {
  1218. struct mg_connection *c = (struct mg_connection *) arg;
  1219. LOG(LL_DEBUG,
  1220. ("err %ld, pbuf %p/%d, io.len %d, io.size %d", err, p,
  1221. p == NULL ? 0 : (int) p->len, (int) c->recv.len, (int) c->recv.size));
  1222. if (err == ERR_OK && p != NULL) {
  1223. #if 0
  1224. if (s->io.size < s->io.len + p->len) {
  1225. char *buf = realloc(s->io.buf, s->io.len + p->len);
  1226. if (buf != NULL) {
  1227. s->io.buf = buf;
  1228. s->io.size = s->io.len + p->len;
  1229. } else {
  1230. return ERR_MEM;
  1231. }
  1232. }
  1233. // MLOG(LL_DEBUG, " --> cpy, %p %p", s->io.buf, p->payload);
  1234. memcpy(s->io.buf + s->io.len, p->payload, p->len);
  1235. s->io.len += p->len;
  1236. #endif
  1237. tcp_recved(pcb, p->len);
  1238. pbuf_free(p);
  1239. return err;
  1240. } else {
  1241. // rmsock(s);
  1242. return ERR_ABRT;
  1243. }
  1244. }
  1245. static void udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p,
  1246. const ip_addr_t *addr, uint16_t port) {
  1247. LOG(LL_DEBUG,
  1248. ("%p %p pbuf %p/%d port %hu", arg, pcb, p, p == NULL ? 0 : p->len, port));
  1249. }
  1250. static err_t tcp_sent_cb(void *arg, struct tcp_pcb *pcb, uint16_t len) {
  1251. LOG(LL_DEBUG, ("%p %d", pcb, (int) len));
  1252. return ERR_OK;
  1253. }
  1254. #if 0
  1255. static int ll_write(struct mg_connection *c, const void *buf, int len,
  1256. int *fail) {
  1257. int n = c->is_tls ? mg_tls_send(c, buf, len, fail)
  1258. : mg_sock_send(c, buf, len, fail);
  1259. LOG(*fail ? LL_ERROR : LL_VERBOSE_DEBUG,
  1260. ("%p %c%c%c %d/%d %d", c->fd, c->is_tls ? 'T' : 't',
  1261. c->is_udp ? 'U' : 'u', c->is_connecting ? 'C' : 'c', n, len,
  1262. MG_SOCK_ERRNO));
  1263. if (n > 0 && c->is_hexdumping) mg_hexdump(c, "->", buf, n);
  1264. return n;
  1265. }
  1266. #endif
  1267. int mg_send(struct mg_connection *c, const void *buf, size_t len) {
  1268. if (c->is_udp) {
  1269. struct udp_pcb *pcb = (struct udp_pcb *) c->fd;
  1270. struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
  1271. if (p != NULL) {
  1272. // p->payload = (void *) buf;
  1273. memcpy(p->payload, buf, len);
  1274. err_t err = udp_send(pcb, p);
  1275. pbuf_free(p);
  1276. LOG(LL_DEBUG,
  1277. ("%lu UDP %d bytes -> %x:%hu, err %ld", c->id, (int) len,
  1278. (unsigned) *(uint32_t *) &pcb->remote_ip, pcb->remote_port, err));
  1279. if (err != ERR_OK) mg_error(c, "%p err %d", c->fd, err);
  1280. } else {
  1281. mg_error(c, "%p pbuf OOM", c->fd);
  1282. }
  1283. } else if (c->is_connecting) {
  1284. mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
  1285. } else {
  1286. }
  1287. #if 0
  1288. int fail, n = c->is_udp
  1289. ? ll_write(c, buf, (SOCKET) len, &fail)
  1290. : mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
  1291. return n;
  1292. #endif
  1293. return 0;
  1294. }
  1295. static struct mg_connection *mg_mkconn(const char *url) {
  1296. struct mg_connection *c = (struct mg_connection *) calloc(1, sizeof(*c));
  1297. typedef void *(*new_t)(void);
  1298. int is_udp = strncmp(url, "udp:", 4) == 0;
  1299. if (c == NULL) {
  1300. LOG(LL_ERROR, ("%s %s", url, "OOM"));
  1301. } else if ((c->fd = (is_udp ? (new_t) udp_new : (new_t) tcp_new)()) == NULL) {
  1302. LOG(LL_ERROR, ("%s new", url));
  1303. free(c);
  1304. c = NULL;
  1305. } else {
  1306. c->is_udp = is_udp;
  1307. }
  1308. return c;
  1309. }
  1310. struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
  1311. mg_event_handler_t fn, void *fn_data) {
  1312. struct mg_connection *c = mg_mkconn(url);
  1313. struct mg_str host = mg_url_host(url);
  1314. if (c == NULL) return c;
  1315. c->next = mgr->conns;
  1316. mgr->conns = c;
  1317. // mg_set_non_blocking_mode((SOCKET) c->fd);
  1318. c->is_client = 1;
  1319. c->peer.port = mg_htons(mg_url_port(url));
  1320. c->fn = fn;
  1321. c->fn_data = fn_data;
  1322. c->is_hexdumping = 1;
  1323. if (c->is_udp) {
  1324. udp_bind(c->fd, IP_ADDR_ANY, 0);
  1325. udp_recv(c->fd, udp_recv_cb, c);
  1326. } else {
  1327. tcp_arg(c->fd, c);
  1328. tcp_err(c->fd, tcp_error_cb);
  1329. tcp_sent(c->fd, tcp_sent_cb);
  1330. tcp_recv(c->fd, tcp_recv_cb);
  1331. tcp_bind(c->fd, IP_ADDR_ANY, 0);
  1332. tcp_nagle_disable((struct tcp_pcb *) c->fd);
  1333. }
  1334. LOG(LL_DEBUG, ("%lu -> %s %s", c->id, url, c->is_udp ? "UDP" : "TCP"));
  1335. mg_resolve(mgr, c, &host, mgr->dnstimeout);
  1336. return c;
  1337. }
  1338. void mg_connect_resolved(struct mg_connection *c) {
  1339. char buf[40];
  1340. ip_addr_t ipaddr;
  1341. memcpy(&ipaddr, &c->peer.ip, sizeof(ipaddr));
  1342. mg_call(c, MG_EV_RESOLVE, NULL);
  1343. LOG(LL_DEBUG, ("%lu resolved to %s", c->id, mg_straddr(c, buf, sizeof(buf))));
  1344. err_t err = c->is_udp ? udp_connect((struct udp_pcb *) c->fd, &ipaddr,
  1345. mg_ntohs(c->peer.port))
  1346. : tcp_connect((struct tcp_pcb *) c->fd, &ipaddr,
  1347. mg_ntohs(c->peer.port), connect_cb);
  1348. if (c->is_udp) c->is_connecting = 0;
  1349. if (err != ERR_OK) mg_error(c, "%p failed, err %d", c->fd, err);
  1350. }
  1351. static err_t accept_cb(void *arg, struct tcp_pcb *pcb, err_t e) {
  1352. LOG(LL_DEBUG, ("%p err %ld, pcb %p", arg, e, pcb));
  1353. return ERR_OK;
  1354. }
  1355. struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
  1356. mg_event_handler_t fn, void *fn_data) {
  1357. struct mg_connection *c = mg_mkconn(url);
  1358. struct mg_str host = mg_url_host(url);
  1359. uint16_t port = mg_url_port(url);
  1360. uint32_t ipaddr;
  1361. err_t err;
  1362. if (c == NULL) return c;
  1363. mg_aton(host.ptr, &ipaddr);
  1364. if (!mg_vcasecmp(&host, "localhost")) ipaddr = mg_htonl(0x7f000001);
  1365. if ((err = tcp_bind(c->fd, (ip_addr_t *) &ipaddr, port)) != ERR_OK) {
  1366. mg_error(c, "%p tcp_bind(%x:%hu) -> %ld", c->fd, ipaddr, port, err);
  1367. } else {
  1368. tcp_listen(c->fd);
  1369. tcp_accept(c->fd, accept_cb);
  1370. }
  1371. return c;
  1372. }
  1373. void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
  1374. LOG(LL_DEBUG, ("%p %d", mgr, ms));
  1375. mg_usleep(200 * 1000);
  1376. mg_timer_poll(mg_millis());
  1377. }
  1378. #endif
  1379. #ifdef MG_ENABLE_LINES
  1380. #line 1 "src/md5.c"
  1381. #endif
  1382. #include <string.h>
  1383. #if MG_ENABLE_MD5
  1384. #if !defined(BYTE_ORDER) && defined(__BYTE_ORDER)
  1385. #define BYTE_ORDER __BYTE_ORDER
  1386. #ifndef LITTLE_ENDIAN
  1387. #define LITTLE_ENDIAN __LITTLE_ENDIAN
  1388. #endif /* LITTLE_ENDIAN */
  1389. #ifndef BIG_ENDIAN
  1390. #define BIG_ENDIAN __LITTLE_ENDIAN
  1391. #endif /* BIG_ENDIAN */
  1392. #endif /* BYTE_ORDER */
  1393. static void mg_byte_reverse(unsigned char *buf, unsigned longs) {
  1394. /* Forrest: MD5 expect LITTLE_ENDIAN, swap if BIG_ENDIAN */
  1395. #if BYTE_ORDER == BIG_ENDIAN
  1396. do {
  1397. uint32_t t = (uint32_t)((unsigned) buf[3] << 8 | buf[2]) << 16 |
  1398. ((unsigned) buf[1] << 8 | buf[0]);
  1399. *(uint32_t *) buf = t;
  1400. buf += 4;
  1401. } while (--longs);
  1402. #else
  1403. (void) buf;
  1404. (void) longs;
  1405. #endif
  1406. }
  1407. #define F1(x, y, z) (z ^ (x & (y ^ z)))
  1408. #define F2(x, y, z) F1(z, x, y)
  1409. #define F3(x, y, z) (x ^ y ^ z)
  1410. #define F4(x, y, z) (y ^ (x | ~z))
  1411. #define MD5STEP(f, w, x, y, z, data, s) \
  1412. (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
  1413. /*
  1414. * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
  1415. * initialization constants.
  1416. */
  1417. void mg_md5_init(mg_md5_ctx *ctx) {
  1418. ctx->buf[0] = 0x67452301;
  1419. ctx->buf[1] = 0xefcdab89;
  1420. ctx->buf[2] = 0x98badcfe;
  1421. ctx->buf[3] = 0x10325476;
  1422. ctx->bits[0] = 0;
  1423. ctx->bits[1] = 0;
  1424. }
  1425. static void mg_md5_transform(uint32_t buf[4], uint32_t const in[16]) {
  1426. uint32_t a, b, c, d;
  1427. a = buf[0];
  1428. b = buf[1];
  1429. c = buf[2];
  1430. d = buf[3];
  1431. MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  1432. MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  1433. MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  1434. MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  1435. MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  1436. MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  1437. MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  1438. MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  1439. MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  1440. MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  1441. MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  1442. MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  1443. MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  1444. MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  1445. MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  1446. MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  1447. MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  1448. MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  1449. MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  1450. MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  1451. MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  1452. MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  1453. MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  1454. MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  1455. MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  1456. MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  1457. MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  1458. MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  1459. MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  1460. MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  1461. MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  1462. MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  1463. MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  1464. MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  1465. MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  1466. MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  1467. MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  1468. MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  1469. MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  1470. MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  1471. MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  1472. MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  1473. MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  1474. MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  1475. MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  1476. MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  1477. MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  1478. MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  1479. MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  1480. MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  1481. MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  1482. MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  1483. MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  1484. MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  1485. MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  1486. MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  1487. MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  1488. MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  1489. MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  1490. MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  1491. MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  1492. MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  1493. MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  1494. MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  1495. buf[0] += a;
  1496. buf[1] += b;
  1497. buf[2] += c;
  1498. buf[3] += d;
  1499. }
  1500. void mg_md5_update(mg_md5_ctx *ctx, const unsigned char *buf, size_t len) {
  1501. uint32_t t;
  1502. t = ctx->bits[0];
  1503. if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++;
  1504. ctx->bits[1] += (uint32_t) len >> 29;
  1505. t = (t >> 3) & 0x3f;
  1506. if (t) {
  1507. unsigned char *p = (unsigned char *) ctx->in + t;
  1508. t = 64 - t;
  1509. if (len < t) {
  1510. memcpy(p, buf, len);
  1511. return;
  1512. }
  1513. memcpy(p, buf, t);
  1514. mg_byte_reverse(ctx->in, 16);
  1515. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  1516. buf += t;
  1517. len -= t;
  1518. }
  1519. while (len >= 64) {
  1520. memcpy(ctx->in, buf, 64);
  1521. mg_byte_reverse(ctx->in, 16);
  1522. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  1523. buf += 64;
  1524. len -= 64;
  1525. }
  1526. memcpy(ctx->in, buf, len);
  1527. }
  1528. void mg_md5_final(mg_md5_ctx *ctx, unsigned char digest[16]) {
  1529. unsigned count;
  1530. unsigned char *p;
  1531. uint32_t *a;
  1532. count = (ctx->bits[0] >> 3) & 0x3F;
  1533. p = ctx->in + count;
  1534. *p++ = 0x80;
  1535. count = 64 - 1 - count;
  1536. if (count < 8) {
  1537. memset(p, 0, count);
  1538. mg_byte_reverse(ctx->in, 16);
  1539. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  1540. memset(ctx->in, 0, 56);
  1541. } else {
  1542. memset(p, 0, count - 8);
  1543. }
  1544. mg_byte_reverse(ctx->in, 14);
  1545. a = (uint32_t *) ctx->in;
  1546. a[14] = ctx->bits[0];
  1547. a[15] = ctx->bits[1];
  1548. mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
  1549. mg_byte_reverse((unsigned char *) ctx->buf, 4);
  1550. memcpy(digest, ctx->buf, 16);
  1551. memset((char *) ctx, 0, sizeof(*ctx));
  1552. }
  1553. #endif
  1554. #ifdef MG_ENABLE_LINES
  1555. #line 1 "src/mqtt.c"
  1556. #endif
  1557. #define MQTT_CLEAN_SESSION 0x02
  1558. #define MQTT_HAS_WILL 0x04
  1559. #define MQTT_WILL_RETAIN 0x20
  1560. #define MQTT_HAS_PASSWORD 0x40
  1561. #define MQTT_HAS_USER_NAME 0x80
  1562. #define MQTT_GET_WILL_QOS(flags) (((flags) &0x18) >> 3)
  1563. #define MQTT_SET_WILL_QOS(flags, qos) (flags) = ((flags) & ~0x18) | ((qos) << 3)
  1564. enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
  1565. void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
  1566. uint32_t len) {
  1567. uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
  1568. buf[0] = (cmd << 4) | flags;
  1569. do {
  1570. *vlen = len % 0x80;
  1571. len /= 0x80;
  1572. if (len > 0) *vlen |= 0x80;
  1573. vlen++;
  1574. } while (len > 0 && vlen < &buf[sizeof(buf)]);
  1575. mg_send(c, buf, vlen - buf);
  1576. }
  1577. static void mg_send_u16(struct mg_connection *c, uint16_t value) {
  1578. mg_send(c, &value, sizeof(value));
  1579. }
  1580. static void mqtt_login(struct mg_connection *c, const char *url,
  1581. struct mg_mqtt_opts *opts) {
  1582. uint32_t total_len = 7 + 1 + 2 + 2;
  1583. uint16_t flags = (opts->qos & 3) << 3;
  1584. struct mg_str user = mg_url_user(url);
  1585. struct mg_str pass = mg_url_pass(url);
  1586. if (user.len > 0) {
  1587. total_len += 2 + (uint32_t) user.len;
  1588. flags |= MQTT_HAS_USER_NAME;
  1589. }
  1590. if (pass.len > 0) {
  1591. total_len += 2 + (uint32_t) pass.len;
  1592. flags |= MQTT_HAS_PASSWORD;
  1593. }
  1594. if (opts->will_topic.len > 0 && opts->will_message.len > 0) {
  1595. total_len +=
  1596. 4 + (uint32_t) opts->will_topic.len + (uint32_t) opts->will_message.len;
  1597. flags |= MQTT_HAS_WILL;
  1598. }
  1599. if (opts->clean || opts->client_id.len == 0) flags |= MQTT_CLEAN_SESSION;
  1600. if (opts->will_retain) flags |= MQTT_WILL_RETAIN;
  1601. total_len += (uint32_t) opts->client_id.len;
  1602. mg_mqtt_send_header(c, MQTT_CMD_CONNECT, 0, total_len);
  1603. mg_send(c, "\00\04MQTT\04", 7);
  1604. mg_send(c, &flags, 1);
  1605. // keepalive == 0 means "do not disconnect us!"
  1606. mg_send_u16(c, mg_htons((uint16_t) opts->keepalive));
  1607. mg_send_u16(c, mg_htons((uint16_t) opts->client_id.len));
  1608. mg_send(c, opts->client_id.ptr, opts->client_id.len);
  1609. if (flags & MQTT_HAS_WILL) {
  1610. mg_send_u16(c, mg_htons((uint16_t) opts->will_topic.len));
  1611. mg_send(c, opts->will_topic.ptr, opts->will_topic.len);
  1612. mg_send_u16(c, mg_htons((uint16_t) opts->will_message.len));
  1613. mg_send(c, opts->will_message.ptr, opts->will_message.len);
  1614. }
  1615. if (user.len > 0) {
  1616. mg_send_u16(c, mg_htons((uint16_t) user.len));
  1617. mg_send(c, user.ptr, user.len);
  1618. }
  1619. if (pass.len > 0) {
  1620. mg_send_u16(c, mg_htons((uint16_t) pass.len));
  1621. mg_send(c, pass.ptr, pass.len);
  1622. }
  1623. }
  1624. void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
  1625. struct mg_str *data) {
  1626. uint8_t flags = MQTT_QOS(1);
  1627. uint32_t total_len = 2 + (uint32_t) topic->len + (uint32_t) data->len;
  1628. LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) topic->len,
  1629. (char *) topic->ptr, (int) data->len, (char *) data->ptr));
  1630. if (MQTT_GET_QOS(flags) > 0) total_len += 2;
  1631. mg_mqtt_send_header(c, MQTT_CMD_PUBLISH, flags, total_len);
  1632. mg_send_u16(c, mg_htons((uint16_t) topic->len));
  1633. mg_send(c, topic->ptr, topic->len);
  1634. if (MQTT_GET_QOS(flags) > 0) {
  1635. static uint16_t s_id;
  1636. if (++s_id == 0) s_id++;
  1637. mg_send_u16(c, mg_htons(s_id));
  1638. }
  1639. mg_send(c, data->ptr, data->len);
  1640. }
  1641. void mg_mqtt_sub(struct mg_connection *c, struct mg_str *topic) {
  1642. static uint16_t s_id;
  1643. uint8_t qos = 1;
  1644. uint32_t total_len = 2 + (uint32_t) topic->len + 2 + 1;
  1645. mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, (uint8_t) MQTT_QOS(qos),
  1646. total_len);
  1647. if (++s_id == 0) ++s_id;
  1648. mg_send_u16(c, mg_htons(s_id));
  1649. mg_send_u16(c, mg_htons((uint16_t) topic->len));
  1650. mg_send(c, topic->ptr, topic->len);
  1651. mg_send(c, &qos, sizeof(qos));
  1652. }
  1653. int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
  1654. uint8_t lc = 0, *p, *end;
  1655. uint32_t n = 0, len_len = 0;
  1656. memset(m, 0, sizeof(*m));
  1657. m->dgram.ptr = (char *) buf;
  1658. if (len < 2) return MQTT_INCOMPLETE;
  1659. m->cmd = buf[0] >> 4;
  1660. m->qos = (buf[0] >> 1) & 3;
  1661. n = len_len = 0;
  1662. p = (uint8_t *) buf + 1;
  1663. while ((size_t)(p - buf) < len) {
  1664. lc = *((uint8_t *) p++);
  1665. n += (lc & 0x7f) << 7 * len_len;
  1666. len_len++;
  1667. if (!(lc & 0x80)) break;
  1668. if (len_len >= 4) return MQTT_MALFORMED;
  1669. }
  1670. end = p + n;
  1671. if (lc & 0x80 || end > buf + len) return MQTT_INCOMPLETE;
  1672. m->dgram.len = end - buf;
  1673. switch (m->cmd) {
  1674. case MQTT_CMD_CONNACK:
  1675. if (end - p < 2) return MQTT_MALFORMED;
  1676. m->ack = p[1];
  1677. break;
  1678. case MQTT_CMD_PUBACK:
  1679. case MQTT_CMD_PUBREC:
  1680. case MQTT_CMD_PUBREL:
  1681. case MQTT_CMD_PUBCOMP:
  1682. case MQTT_CMD_SUBACK:
  1683. if (p + 2 > end) return MQTT_MALFORMED;
  1684. m->id = (p[0] << 8) | p[1];
  1685. break;
  1686. case MQTT_CMD_SUBSCRIBE: {
  1687. if (p + 2 > end) return MQTT_MALFORMED;
  1688. m->id = (p[0] << 8) | p[1];
  1689. p += 2;
  1690. break;
  1691. }
  1692. case MQTT_CMD_PUBLISH: {
  1693. if (p + 2 > end) return MQTT_MALFORMED;
  1694. m->topic.len = (p[0] << 8) | p[1];
  1695. m->topic.ptr = (char *) p + 2;
  1696. p += 2 + m->topic.len;
  1697. if (p > end) return MQTT_MALFORMED;
  1698. if (m->qos > 0) {
  1699. if (p + 2 > end) return MQTT_MALFORMED;
  1700. m->id = (p[0] << 8) | p[1];
  1701. p += 2;
  1702. }
  1703. if (p > end) return MQTT_MALFORMED;
  1704. m->data.ptr = (char *) p;
  1705. m->data.len = end - p;
  1706. break;
  1707. }
  1708. default:
  1709. break;
  1710. }
  1711. return MQTT_OK;
  1712. }
  1713. int mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
  1714. uint8_t *qos, int pos) {
  1715. unsigned char *buf = (unsigned char *) msg->dgram.ptr + pos;
  1716. int new_pos;
  1717. if ((size_t) pos >= msg->dgram.len) return -1;
  1718. topic->len = buf[0] << 8 | buf[1];
  1719. topic->ptr = (char *) buf + 2;
  1720. new_pos = pos + 2 + topic->len + 1;
  1721. if ((size_t) new_pos > msg->dgram.len) return -1;
  1722. *qos = buf[2 + topic->len];
  1723. return new_pos;
  1724. }
  1725. static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
  1726. void *fn_data) {
  1727. if (ev == MG_EV_READ) {
  1728. for (;;) {
  1729. struct mg_mqtt_message mm;
  1730. int rc = mg_mqtt_parse(c->recv.buf, c->recv.len, &mm);
  1731. if (rc == MQTT_MALFORMED) {
  1732. LOG(LL_ERROR, ("%lu MQTT malformed message", c->id));
  1733. c->is_closing = 1;
  1734. break;
  1735. } else if (rc == MQTT_OK) {
  1736. LOG(LL_VERBOSE_DEBUG,
  1737. ("%p MQTT CMD %d len %d [%.*s]", c->fd, mm.cmd, (int) mm.dgram.len,
  1738. (int) mm.data.len, mm.data.ptr));
  1739. switch (mm.cmd) {
  1740. case MQTT_CMD_CONNACK:
  1741. mg_call(c, MG_EV_MQTT_OPEN, &mm.ack);
  1742. if (mm.ack == 0) {
  1743. LOG(LL_INFO, ("%lu Connected", c->id));
  1744. } else {
  1745. LOG(LL_ERROR, ("%lu MQTT auth failed, code %d", c->id, mm.ack));
  1746. c->is_closing = 1;
  1747. }
  1748. break;
  1749. case MQTT_CMD_PUBLISH: {
  1750. LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) mm.topic.len,
  1751. mm.topic.ptr, (int) mm.data.len, mm.data.ptr));
  1752. mg_call(c, MG_EV_MQTT_MSG, &mm);
  1753. break;
  1754. }
  1755. }
  1756. mg_call(c, MG_EV_MQTT_CMD, &mm);
  1757. mg_iobuf_delete(&c->recv, mm.dgram.len);
  1758. } else {
  1759. break;
  1760. }
  1761. }
  1762. }
  1763. (void) ev_data;
  1764. (void) fn_data;
  1765. }
  1766. struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url,
  1767. struct mg_mqtt_opts *opts,
  1768. mg_event_handler_t fn, void *fn_data) {
  1769. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  1770. if (c != NULL) {
  1771. struct mg_mqtt_opts empty;
  1772. memset(&empty, 0, sizeof(empty));
  1773. mqtt_login(c, url, opts == NULL ? &empty : opts);
  1774. c->pfn = mqtt_cb;
  1775. }
  1776. return c;
  1777. }
  1778. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  1779. mg_event_handler_t fn, void *fn_data) {
  1780. struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
  1781. if (c != NULL) c->pfn = mqtt_cb, c->pfn_data = mgr;
  1782. return c;
  1783. }
  1784. #ifdef MG_ENABLE_LINES
  1785. #line 1 "src/net.c"
  1786. #endif
  1787. int mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) {
  1788. char mem[256], *buf = mem;
  1789. int len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
  1790. len = mg_send(c, buf, len);
  1791. if (buf != mem) free(buf);
  1792. return len;
  1793. }
  1794. int mg_printf(struct mg_connection *c, const char *fmt, ...) {
  1795. int len = 0;
  1796. va_list ap;
  1797. va_start(ap, fmt);
  1798. len = mg_vprintf(c, fmt, ap);
  1799. va_end(ap);
  1800. return len;
  1801. }
  1802. char *mg_straddr(struct mg_connection *c, char *buf, size_t len) {
  1803. char tmp[100];
  1804. const char *fmt = c->peer.is_ip6 ? "[%s]:%d" : "%s:%d";
  1805. mg_ntoa(&c->peer, tmp, sizeof(tmp));
  1806. snprintf(buf, len, fmt, tmp, (int) mg_ntohs(c->peer.port));
  1807. return buf;
  1808. }
  1809. char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len) {
  1810. if (addr->is_ip6) {
  1811. uint16_t *p = (uint16_t *) addr->ip6;
  1812. snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x", mg_htons(p[0]),
  1813. mg_htons(p[1]), mg_htons(p[2]), mg_htons(p[3]), mg_htons(p[4]),
  1814. mg_htons(p[5]), mg_htons(p[6]), mg_htons(p[7]));
  1815. } else {
  1816. uint8_t p[4];
  1817. memcpy(p, &addr->ip, sizeof(p));
  1818. snprintf(buf, len, "%d.%d.%d.%d", (int) p[0], (int) p[1], (int) p[2],
  1819. (int) p[3]);
  1820. }
  1821. return buf;
  1822. }
  1823. static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
  1824. if (mg_vcasecmp(&str, "localhost") != 0) return false;
  1825. addr->ip = mg_htonl(0x7f000001);
  1826. addr->is_ip6 = false;
  1827. return true;
  1828. }
  1829. static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
  1830. uint8_t data[4] = {0, 0, 0, 0};
  1831. size_t i, num_dots = 0;
  1832. for (i = 0; i < str.len; i++) {
  1833. if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
  1834. int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
  1835. if (octet > 255) return false;
  1836. data[num_dots] = octet;
  1837. } else if (str.ptr[i] == '.') {
  1838. if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
  1839. num_dots++;
  1840. } else {
  1841. return false;
  1842. }
  1843. }
  1844. if (num_dots != 3 || str.ptr[i - 1] == '.') return false;
  1845. memcpy(&addr->ip, data, sizeof(data));
  1846. addr->is_ip6 = false;
  1847. return true;
  1848. }
  1849. static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
  1850. size_t i, j = 0, n = 0, dc = 42;
  1851. for (i = 0; i < str.len; i++) {
  1852. if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') ||
  1853. (str.ptr[i] >= 'a' && str.ptr[i] <= 'f') ||
  1854. (str.ptr[i] >= 'A' && str.ptr[i] <= 'F')) {
  1855. unsigned long val;
  1856. if (i > j + 3) return false;
  1857. // LOG(LL_DEBUG, ("%zu %zu [%.*s]", i, j, (int) (i - j + 1),
  1858. // &str.ptr[j]));
  1859. val = mg_unhexn(&str.ptr[j], i - j + 1);
  1860. addr->ip6[n] = (uint8_t)((val >> 8) & 255);
  1861. addr->ip6[n + 1] = (uint8_t)(val & 255);
  1862. } else if (str.ptr[i] == ':') {
  1863. j = i + 1;
  1864. if (i > 0 && str.ptr[i - 1] == ':') {
  1865. dc = n; // Double colon
  1866. if (i > 1 && str.ptr[i - 2] == ':') return false;
  1867. } else if (i > 0) {
  1868. n += 2;
  1869. }
  1870. if (n > 14) return false;
  1871. addr->ip6[n] = addr->ip6[n + 1] = 0; // For trailing ::
  1872. } else {
  1873. return false;
  1874. }
  1875. }
  1876. if (n < 14 && dc == 42) return false;
  1877. if (n < 14) {
  1878. memmove(&addr->ip6[dc + (14 - n)], &addr->ip6[dc], n - dc + 2);
  1879. memset(&addr->ip6[dc], 0, 14 - n);
  1880. }
  1881. addr->is_ip6 = true;
  1882. return true;
  1883. }
  1884. bool mg_aton(struct mg_str str, struct mg_addr *addr) {
  1885. // LOG(LL_INFO, ("[%.*s]", (int) str.len, str.ptr));
  1886. return mg_atonl(str, addr) || mg_aton4(str, addr) || mg_aton6(str, addr);
  1887. }
  1888. void mg_mgr_free(struct mg_mgr *mgr) {
  1889. struct mg_connection *c;
  1890. for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
  1891. mg_mgr_poll(mgr, 0);
  1892. #if MG_ARCH == MG_ARCH_FREERTOS
  1893. FreeRTOS_DeleteSocketSet(mgr->ss);
  1894. #endif
  1895. LOG(LL_INFO, ("All connections closed"));
  1896. }
  1897. void mg_mgr_init(struct mg_mgr *mgr) {
  1898. #ifdef _WIN32
  1899. WSADATA data;
  1900. WSAStartup(MAKEWORD(2, 2), &data);
  1901. #elif MG_ARCH == MG_ARCH_FREERTOS
  1902. mgr->ss = FreeRTOS_CreateSocketSet();
  1903. #elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
  1904. // Ignore SIGPIPE signal, so if client cancels the request, it
  1905. // won't kill the whole process.
  1906. signal(SIGPIPE, SIG_IGN);
  1907. #endif
  1908. memset(mgr, 0, sizeof(*mgr));
  1909. mgr->dnstimeout = 3000;
  1910. mgr->dns4.url = "udp://8.8.8.8:53";
  1911. mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
  1912. }
  1913. #ifdef MG_ENABLE_LINES
  1914. #line 1 "src/sha1.c"
  1915. #endif
  1916. /* Copyright(c) By Steve Reid <steve@edmweb.com> */
  1917. /* 100% Public Domain */
  1918. #include <string.h>
  1919. /*
  1920. * clang with std=-c99 uses __LITTLE_ENDIAN, by default
  1921. * while for ex, RTOS gcc - LITTLE_ENDIAN, by default
  1922. * it depends on __USE_BSD, but let's have everything
  1923. */
  1924. #if !defined(BYTE_ORDER) && defined(__BYTE_ORDER)
  1925. #define BYTE_ORDER __BYTE_ORDER
  1926. #ifndef LITTLE_ENDIAN
  1927. #define LITTLE_ENDIAN __LITTLE_ENDIAN
  1928. #endif /* LITTLE_ENDIAN */
  1929. #ifndef BIG_ENDIAN
  1930. #define BIG_ENDIAN __LITTLE_ENDIAN
  1931. #endif /* BIG_ENDIAN */
  1932. #endif /* BYTE_ORDER */
  1933. union char64long16 {
  1934. unsigned char c[64];
  1935. uint32_t l[16];
  1936. };
  1937. #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  1938. static uint32_t blk0(union char64long16 *block, int i) {
  1939. /* Forrest: SHA expect BIG_ENDIAN, swap if LITTLE_ENDIAN */
  1940. #if BYTE_ORDER == LITTLE_ENDIAN
  1941. block->l[i] =
  1942. (rol(block->l[i], 24) & 0xFF00FF00) | (rol(block->l[i], 8) & 0x00FF00FF);
  1943. #endif
  1944. return block->l[i];
  1945. }
  1946. /* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */
  1947. #undef blk
  1948. #undef R0
  1949. #undef R1
  1950. #undef R2
  1951. #undef R3
  1952. #undef R4
  1953. #define blk(i) \
  1954. (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \
  1955. block->l[(i + 2) & 15] ^ block->l[i & 15], \
  1956. 1))
  1957. #define R0(v, w, x, y, z, i) \
  1958. z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \
  1959. w = rol(w, 30);
  1960. #define R1(v, w, x, y, z, i) \
  1961. z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
  1962. w = rol(w, 30);
  1963. #define R2(v, w, x, y, z, i) \
  1964. z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
  1965. w = rol(w, 30);
  1966. #define R3(v, w, x, y, z, i) \
  1967. z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
  1968. w = rol(w, 30);
  1969. #define R4(v, w, x, y, z, i) \
  1970. z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
  1971. w = rol(w, 30);
  1972. void mg_sha1_transform(uint32_t state[5], const unsigned char buffer[64]) {
  1973. uint32_t a, b, c, d, e;
  1974. union char64long16 block[1];
  1975. memcpy(block, buffer, 64);
  1976. a = state[0];
  1977. b = state[1];
  1978. c = state[2];
  1979. d = state[3];
  1980. e = state[4];
  1981. R0(a, b, c, d, e, 0);
  1982. R0(e, a, b, c, d, 1);
  1983. R0(d, e, a, b, c, 2);
  1984. R0(c, d, e, a, b, 3);
  1985. R0(b, c, d, e, a, 4);
  1986. R0(a, b, c, d, e, 5);
  1987. R0(e, a, b, c, d, 6);
  1988. R0(d, e, a, b, c, 7);
  1989. R0(c, d, e, a, b, 8);
  1990. R0(b, c, d, e, a, 9);
  1991. R0(a, b, c, d, e, 10);
  1992. R0(e, a, b, c, d, 11);
  1993. R0(d, e, a, b, c, 12);
  1994. R0(c, d, e, a, b, 13);
  1995. R0(b, c, d, e, a, 14);
  1996. R0(a, b, c, d, e, 15);
  1997. R1(e, a, b, c, d, 16);
  1998. R1(d, e, a, b, c, 17);
  1999. R1(c, d, e, a, b, 18);
  2000. R1(b, c, d, e, a, 19);
  2001. R2(a, b, c, d, e, 20);
  2002. R2(e, a, b, c, d, 21);
  2003. R2(d, e, a, b, c, 22);
  2004. R2(c, d, e, a, b, 23);
  2005. R2(b, c, d, e, a, 24);
  2006. R2(a, b, c, d, e, 25);
  2007. R2(e, a, b, c, d, 26);
  2008. R2(d, e, a, b, c, 27);
  2009. R2(c, d, e, a, b, 28);
  2010. R2(b, c, d, e, a, 29);
  2011. R2(a, b, c, d, e, 30);
  2012. R2(e, a, b, c, d, 31);
  2013. R2(d, e, a, b, c, 32);
  2014. R2(c, d, e, a, b, 33);
  2015. R2(b, c, d, e, a, 34);
  2016. R2(a, b, c, d, e, 35);
  2017. R2(e, a, b, c, d, 36);
  2018. R2(d, e, a, b, c, 37);
  2019. R2(c, d, e, a, b, 38);
  2020. R2(b, c, d, e, a, 39);
  2021. R3(a, b, c, d, e, 40);
  2022. R3(e, a, b, c, d, 41);
  2023. R3(d, e, a, b, c, 42);
  2024. R3(c, d, e, a, b, 43);
  2025. R3(b, c, d, e, a, 44);
  2026. R3(a, b, c, d, e, 45);
  2027. R3(e, a, b, c, d, 46);
  2028. R3(d, e, a, b, c, 47);
  2029. R3(c, d, e, a, b, 48);
  2030. R3(b, c, d, e, a, 49);
  2031. R3(a, b, c, d, e, 50);
  2032. R3(e, a, b, c, d, 51);
  2033. R3(d, e, a, b, c, 52);
  2034. R3(c, d, e, a, b, 53);
  2035. R3(b, c, d, e, a, 54);
  2036. R3(a, b, c, d, e, 55);
  2037. R3(e, a, b, c, d, 56);
  2038. R3(d, e, a, b, c, 57);
  2039. R3(c, d, e, a, b, 58);
  2040. R3(b, c, d, e, a, 59);
  2041. R4(a, b, c, d, e, 60);
  2042. R4(e, a, b, c, d, 61);
  2043. R4(d, e, a, b, c, 62);
  2044. R4(c, d, e, a, b, 63);
  2045. R4(b, c, d, e, a, 64);
  2046. R4(a, b, c, d, e, 65);
  2047. R4(e, a, b, c, d, 66);
  2048. R4(d, e, a, b, c, 67);
  2049. R4(c, d, e, a, b, 68);
  2050. R4(b, c, d, e, a, 69);
  2051. R4(a, b, c, d, e, 70);
  2052. R4(e, a, b, c, d, 71);
  2053. R4(d, e, a, b, c, 72);
  2054. R4(c, d, e, a, b, 73);
  2055. R4(b, c, d, e, a, 74);
  2056. R4(a, b, c, d, e, 75);
  2057. R4(e, a, b, c, d, 76);
  2058. R4(d, e, a, b, c, 77);
  2059. R4(c, d, e, a, b, 78);
  2060. R4(b, c, d, e, a, 79);
  2061. state[0] += a;
  2062. state[1] += b;
  2063. state[2] += c;
  2064. state[3] += d;
  2065. state[4] += e;
  2066. /* Erase working structures. The order of operations is important,
  2067. * used to ensure that compiler doesn't optimize those out. */
  2068. memset(block, 0, sizeof(block));
  2069. a = b = c = d = e = 0;
  2070. (void) a;
  2071. (void) b;
  2072. (void) c;
  2073. (void) d;
  2074. (void) e;
  2075. }
  2076. void mg_sha1_init(mg_sha1_ctx *context) {
  2077. context->state[0] = 0x67452301;
  2078. context->state[1] = 0xEFCDAB89;
  2079. context->state[2] = 0x98BADCFE;
  2080. context->state[3] = 0x10325476;
  2081. context->state[4] = 0xC3D2E1F0;
  2082. context->count[0] = context->count[1] = 0;
  2083. }
  2084. void mg_sha1_update(mg_sha1_ctx *context, const unsigned char *data,
  2085. size_t len) {
  2086. size_t i, j;
  2087. j = context->count[0];
  2088. if ((context->count[0] += (uint32_t) len << 3) < j) context->count[1]++;
  2089. context->count[1] += (uint32_t)(len >> 29);
  2090. j = (j >> 3) & 63;
  2091. if ((j + len) > 63) {
  2092. memcpy(&context->buffer[j], data, (i = 64 - j));
  2093. mg_sha1_transform(context->state, context->buffer);
  2094. for (; i + 63 < len; i += 64) {
  2095. mg_sha1_transform(context->state, &data[i]);
  2096. }
  2097. j = 0;
  2098. } else
  2099. i = 0;
  2100. memcpy(&context->buffer[j], &data[i], len - i);
  2101. }
  2102. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *context) {
  2103. unsigned i;
  2104. unsigned char finalcount[8], c;
  2105. for (i = 0; i < 8; i++) {
  2106. finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >>
  2107. ((3 - (i & 3)) * 8)) &
  2108. 255);
  2109. }
  2110. c = 0200;
  2111. mg_sha1_update(context, &c, 1);
  2112. while ((context->count[0] & 504) != 448) {
  2113. c = 0000;
  2114. mg_sha1_update(context, &c, 1);
  2115. }
  2116. mg_sha1_update(context, finalcount, 8);
  2117. for (i = 0; i < 20; i++) {
  2118. digest[i] =
  2119. (unsigned char) ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
  2120. }
  2121. memset(context, '\0', sizeof(*context));
  2122. memset(&finalcount, '\0', sizeof(finalcount));
  2123. }
  2124. void mg_hmac_sha1(const unsigned char *key, size_t keylen,
  2125. const unsigned char *data, size_t datalen,
  2126. unsigned char out[20]) {
  2127. mg_sha1_ctx ctx;
  2128. unsigned char buf1[64], buf2[64], tmp_key[20], i;
  2129. if (keylen > sizeof(buf1)) {
  2130. mg_sha1_init(&ctx);
  2131. mg_sha1_update(&ctx, key, keylen);
  2132. mg_sha1_final(tmp_key, &ctx);
  2133. key = tmp_key;
  2134. keylen = sizeof(tmp_key);
  2135. }
  2136. memset(buf1, 0, sizeof(buf1));
  2137. memset(buf2, 0, sizeof(buf2));
  2138. memcpy(buf1, key, keylen);
  2139. memcpy(buf2, key, keylen);
  2140. for (i = 0; i < sizeof(buf1); i++) {
  2141. buf1[i] ^= 0x36;
  2142. buf2[i] ^= 0x5c;
  2143. }
  2144. mg_sha1_init(&ctx);
  2145. mg_sha1_update(&ctx, buf1, sizeof(buf1));
  2146. mg_sha1_update(&ctx, data, datalen);
  2147. mg_sha1_final(out, &ctx);
  2148. mg_sha1_init(&ctx);
  2149. mg_sha1_update(&ctx, buf2, sizeof(buf2));
  2150. mg_sha1_update(&ctx, out, 20);
  2151. mg_sha1_final(out, &ctx);
  2152. }
  2153. #ifdef MG_ENABLE_LINES
  2154. #line 1 "src/sntp.c"
  2155. #endif
  2156. #define SNTP_INTERVAL_SEC (3600)
  2157. #define SNTP_TIME_OFFSET 2208988800
  2158. static unsigned long s_sntmp_next;
  2159. int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv) {
  2160. int mode = len > 0 ? buf[0] & 7 : 0, res = -1;
  2161. if (len < 48) {
  2162. LOG(LL_ERROR, ("%s", "corrupt packet"));
  2163. } else if ((buf[0] & 0x38) >> 3 != 4) {
  2164. LOG(LL_ERROR, ("%s", "wrong version"));
  2165. } else if (mode != 4 && mode != 5) {
  2166. LOG(LL_ERROR, ("%s", "not a server reply"));
  2167. } else if (buf[1] == 0) {
  2168. LOG(LL_ERROR, ("%s", "server sent a kiss of death"));
  2169. } else {
  2170. uint32_t *data = (uint32_t *) &buf[40];
  2171. tv->tv_sec = mg_ntohl(data[0]) - SNTP_TIME_OFFSET;
  2172. tv->tv_usec = mg_ntohl(data[1]);
  2173. s_sntmp_next = tv->tv_sec + SNTP_INTERVAL_SEC;
  2174. res = 0;
  2175. }
  2176. return res;
  2177. }
  2178. static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
  2179. if (ev == MG_EV_READ) {
  2180. struct timeval tv = {0, 0};
  2181. if (mg_sntp_parse(c->recv.buf, c->recv.len, &tv) == 0) {
  2182. mg_call(c, MG_EV_SNTP_TIME, &tv);
  2183. LOG(LL_DEBUG, ("%u.%u, next at %lu", (unsigned) tv.tv_sec,
  2184. (unsigned) tv.tv_usec, s_sntmp_next));
  2185. }
  2186. c->recv.len = 0; // Clear receive buffer
  2187. } else if (ev == MG_EV_RESOLVE) {
  2188. mg_sntp_send(c, time(NULL));
  2189. } else if (ev == MG_EV_CLOSE) {
  2190. // mg_fn_del(c, sntp_cb);
  2191. }
  2192. (void) fnd;
  2193. (void) evd;
  2194. }
  2195. void mg_sntp_send(struct mg_connection *c, unsigned long utc) {
  2196. if (c->is_resolving) {
  2197. LOG(LL_ERROR, ("%lu wait until resolved", c->id));
  2198. } else if (utc > s_sntmp_next) {
  2199. uint8_t buf[48] = {0};
  2200. s_sntmp_next = utc + SNTP_INTERVAL_SEC;
  2201. buf[0] = (3 << 6) | (4 << 3) | 3;
  2202. mg_send(c, buf, sizeof(buf));
  2203. LOG(LL_DEBUG,
  2204. ("%p request sent, ct %lu, next at %lu", c->fd, utc, s_sntmp_next));
  2205. }
  2206. }
  2207. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  2208. mg_event_handler_t fn, void *fnd) {
  2209. struct mg_connection *c = NULL;
  2210. if (url == NULL) url = "udp://time.google.com:123";
  2211. if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) c->pfn = sntp_cb;
  2212. return c;
  2213. }
  2214. #ifdef MG_ENABLE_LINES
  2215. #line 1 "src/sock.c"
  2216. #endif
  2217. #if MG_ENABLE_SOCKET
  2218. #if defined(_WIN32)
  2219. #define MG_SOCK_ERRNO WSAGetLastError()
  2220. #define FD(C_) ((SOCKET)(C_)->fd)
  2221. #ifndef SO_EXCLUSIVEADDRUSE
  2222. #define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
  2223. #endif
  2224. #elif MG_ARCH == MG_ARCH_FREERTOS
  2225. #define MG_SOCK_ERRNO errno
  2226. typedef Socket_t SOCKET;
  2227. #define FD(C_) ((long) (C_)->fd)
  2228. #define INVALID_SOCKET FREERTOS_INVALID_SOCKET
  2229. #else
  2230. #define MG_SOCK_ERRNO errno
  2231. #define closesocket(x) close(x)
  2232. #define INVALID_SOCKET (-1)
  2233. typedef int SOCKET;
  2234. #define FD(C_) ((SOCKET)(long) (C_)->fd)
  2235. #endif
  2236. #ifndef MSG_NONBLOCKING
  2237. #define MSG_NONBLOCKING 0
  2238. #endif
  2239. union usa {
  2240. struct sockaddr sa;
  2241. struct sockaddr_in sin;
  2242. #if MG_ENABLE_IPV6
  2243. struct sockaddr_in6 sin6;
  2244. #endif
  2245. };
  2246. static union usa tousa(struct mg_addr *a) {
  2247. union usa usa;
  2248. memset(&usa, 0, sizeof(usa));
  2249. usa.sin.sin_family = AF_INET;
  2250. usa.sin.sin_port = a->port;
  2251. *(uint32_t *) &usa.sin.sin_addr = a->ip;
  2252. #if MG_ENABLE_IPV6
  2253. if (a->is_ip6) {
  2254. usa.sin.sin_family = AF_INET6;
  2255. usa.sin6.sin6_port = a->port;
  2256. memcpy(&usa.sin6.sin6_addr, a->ip6, sizeof(a->ip6));
  2257. }
  2258. #endif
  2259. return usa;
  2260. }
  2261. static int mg_sock_failed(void) {
  2262. int err = MG_SOCK_ERRNO;
  2263. return err != EINPROGRESS && err != EWOULDBLOCK
  2264. #ifndef WINCE
  2265. && err != EAGAIN && err != EINTR
  2266. #endif
  2267. #ifdef _WIN32
  2268. && err != WSAEINTR && err != WSAEWOULDBLOCK
  2269. #endif
  2270. ;
  2271. }
  2272. static struct mg_connection *alloc_conn(struct mg_mgr *mgr, int is_client,
  2273. SOCKET fd) {
  2274. struct mg_connection *c = (struct mg_connection *) calloc(1, sizeof(*c));
  2275. if (c != NULL) {
  2276. c->is_client = is_client;
  2277. c->fd = (void *) (long) fd;
  2278. c->mgr = mgr;
  2279. c->id = ++mgr->nextid;
  2280. }
  2281. return c;
  2282. }
  2283. static int mg_sock_recv(struct mg_connection *c, void *buf, int len,
  2284. int *fail) {
  2285. int n = 0;
  2286. if (c->is_udp) {
  2287. union usa usa;
  2288. socklen_t slen = sizeof(usa.sin);
  2289. #if MG_ENABLE_IPV6
  2290. if (c->peer.is_ip6) slen = sizeof(usa.sin6);
  2291. #endif
  2292. n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
  2293. if (n > 0) {
  2294. if (c->peer.is_ip6) {
  2295. #if MG_ENABLE_IPV6
  2296. memcpy(c->peer.ip6, &usa.sin6.sin6_addr, sizeof(c->peer.ip6));
  2297. c->peer.port = usa.sin6.sin6_port;
  2298. #endif
  2299. } else {
  2300. c->peer.ip = *(uint32_t *) &usa.sin.sin_addr;
  2301. c->peer.port = usa.sin.sin_port;
  2302. }
  2303. }
  2304. } else {
  2305. n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
  2306. }
  2307. *fail = (n == 0) || (n < 0 && mg_sock_failed());
  2308. return n;
  2309. }
  2310. static int mg_sock_send(struct mg_connection *c, const void *buf, int len,
  2311. int *fail) {
  2312. int n = 0;
  2313. if (c->is_udp) {
  2314. union usa usa = tousa(&c->peer);
  2315. socklen_t slen = sizeof(usa.sin);
  2316. #if MG_ENABLE_IPV6
  2317. if (c->peer.is_ip6) slen = sizeof(usa.sin6);
  2318. #endif
  2319. n = sendto(FD(c), (char *) buf, len, 0, &usa.sa, slen);
  2320. } else {
  2321. n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
  2322. }
  2323. *fail = (n == 0) || (n < 0 && mg_sock_failed());
  2324. return n;
  2325. }
  2326. static int ll_read(struct mg_connection *c, void *buf, int len, int *fail) {
  2327. int n = c->is_tls ? mg_tls_recv(c, buf, len, fail)
  2328. : mg_sock_recv(c, buf, len, fail);
  2329. LOG(*fail ? LL_DEBUG : LL_VERBOSE_DEBUG,
  2330. ("%lu %c%c%c %d/%d %d %d", c->id, c->is_tls ? 'T' : 't',
  2331. c->is_udp ? 'U' : 'u', c->is_connecting ? 'C' : 'c', n, len,
  2332. MG_SOCK_ERRNO, *fail));
  2333. if (n > 0 && c->is_hexdumping) {
  2334. char *s = mg_hexdump(buf, n);
  2335. // LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "<-", n, s));
  2336. free(s);
  2337. }
  2338. return n;
  2339. }
  2340. static int ll_write(struct mg_connection *c, const void *buf, int len,
  2341. int *fail) {
  2342. int n = c->is_tls ? mg_tls_send(c, buf, len, fail)
  2343. : mg_sock_send(c, buf, len, fail);
  2344. LOG(*fail ? LL_ERROR : LL_VERBOSE_DEBUG,
  2345. ("%lu %c%c%c %d/%d %d", c->id, c->is_tls ? 'T' : 't',
  2346. c->is_udp ? 'U' : 'u', c->is_connecting ? 'C' : 'c', n, len,
  2347. MG_SOCK_ERRNO));
  2348. if (n > 0 && c->is_hexdumping) {
  2349. char *s = mg_hexdump(buf, len);
  2350. // LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "->", len, s));
  2351. free(s);
  2352. }
  2353. return n;
  2354. }
  2355. int mg_send(struct mg_connection *c, const void *buf, size_t len) {
  2356. int fail, n = c->is_udp
  2357. ? ll_write(c, buf, (SOCKET) len, &fail)
  2358. : (int) mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
  2359. if (len > 0 && n == 0) fail = 1;
  2360. return n;
  2361. }
  2362. static void mg_set_non_blocking_mode(SOCKET fd) {
  2363. #ifdef _WIN32
  2364. unsigned long on = 1;
  2365. ioctlsocket(fd, FIONBIO, &on);
  2366. #elif MG_ARCH == MG_ARCH_FREERTOS
  2367. const BaseType_t off = 0;
  2368. setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off));
  2369. setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off));
  2370. #else
  2371. fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
  2372. #endif
  2373. }
  2374. SOCKET mg_open_listener(const char *url) {
  2375. struct mg_addr addr;
  2376. SOCKET fd = INVALID_SOCKET;
  2377. memset(&addr, 0, sizeof(addr));
  2378. addr.port = mg_htons(mg_url_port(url));
  2379. if (!mg_aton(mg_url_host(url), &addr)) {
  2380. LOG(LL_ERROR, ("invalid listening URL: %s", url));
  2381. } else {
  2382. union usa usa = tousa(&addr);
  2383. int on = 1, af = AF_INET;
  2384. int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
  2385. int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
  2386. socklen_t slen = sizeof(usa.sin);
  2387. #if MG_ENABLE_IPV6
  2388. if (addr.is_ip6) af = AF_INET6, slen = sizeof(usa.sin6);
  2389. #endif
  2390. if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
  2391. #if !defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)
  2392. // SO_RESUSEADDR is not enabled on Windows because the semantics of
  2393. // SO_REUSEADDR on UNIX and Windows is different. On Windows,
  2394. // SO_REUSEADDR allows to bind a socket to a port without error even if
  2395. // the port is already open by another program. This is not the behavior
  2396. // SO_REUSEADDR was designed for, and leads to hard-to-track failure
  2397. // scenarios. Therefore, SO_REUSEADDR was disabled on Windows unless
  2398. // SO_EXCLUSIVEADDRUSE is supported and set on a socket.
  2399. !setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) &&
  2400. #endif
  2401. #if defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
  2402. // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
  2403. //! setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof(on))
  2404. //! &&
  2405. !setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &on,
  2406. sizeof(on)) &&
  2407. #endif
  2408. bind(fd, &usa.sa, slen) == 0 &&
  2409. // NOTE(lsm): FreeRTOS uses backlog value as a connection limit
  2410. (type == SOCK_DGRAM || listen(fd, 128) == 0)) {
  2411. mg_set_non_blocking_mode(fd);
  2412. } else if (fd != INVALID_SOCKET) {
  2413. LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, MG_SOCK_ERRNO));
  2414. closesocket(fd);
  2415. fd = INVALID_SOCKET;
  2416. }
  2417. }
  2418. return fd;
  2419. }
  2420. static void read_conn(struct mg_connection *c,
  2421. int (*fn)(struct mg_connection *, void *, int, int *)) {
  2422. unsigned char *buf;
  2423. int rc, len, fail;
  2424. // NOTE(lsm): do only one iteration of reads, cause some systems
  2425. // (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
  2426. if (c->recv.size - c->recv.len < MG_IO_SIZE &&
  2427. c->recv.size < MG_MAX_RECV_BUF_SIZE &&
  2428. !mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE)) {
  2429. c->is_closing = 1;
  2430. }
  2431. buf = c->recv.buf + c->recv.len;
  2432. len = (int) (c->recv.size - c->recv.len);
  2433. rc = fn(c, buf, len, &fail);
  2434. if (rc > 0) {
  2435. struct mg_str evd = mg_str_n((char *) buf, rc);
  2436. c->recv.len += rc;
  2437. mg_call(c, MG_EV_READ, &evd);
  2438. } else {
  2439. if (fail) c->is_closing = 1;
  2440. }
  2441. }
  2442. static int write_conn(struct mg_connection *c) {
  2443. int fail, rc = ll_write(c, c->send.buf, (SOCKET) c->send.len, &fail);
  2444. if (rc > 0) {
  2445. mg_iobuf_delete(&c->send, rc);
  2446. if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
  2447. mg_call(c, MG_EV_WRITE, &rc);
  2448. } else if (fail) {
  2449. c->is_closing = 1;
  2450. }
  2451. return rc;
  2452. }
  2453. static void close_conn(struct mg_connection *c) {
  2454. // Unlink this connection from the list
  2455. LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
  2456. mg_resolve_cancel(c);
  2457. if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
  2458. if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
  2459. mg_call(c, MG_EV_CLOSE, NULL);
  2460. // while (c->callbacks != NULL) mg_fn_del(c, c->callbacks->fn);
  2461. LOG(LL_DEBUG, ("%lu closed", c->id));
  2462. if (FD(c) != INVALID_SOCKET) {
  2463. closesocket(FD(c));
  2464. #if MG_ARCH == MG_ARCH_FREERTOS
  2465. FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL);
  2466. #endif
  2467. }
  2468. mg_tls_free(c);
  2469. free(c->recv.buf);
  2470. free(c->send.buf);
  2471. memset(c, 0, sizeof(*c));
  2472. free(c);
  2473. }
  2474. static void setsockopts(struct mg_connection *c) {
  2475. #if MG_ARCH == MG_ARCH_FREERTOS
  2476. FreeRTOS_FD_SET(c->fd, c->mgr->ss, eSELECT_READ | eSELECT_EXCEPT);
  2477. #else
  2478. int on = 1;
  2479. #if !defined(SOL_TCP)
  2480. #define SOL_TCP IPPROTO_TCP
  2481. #endif
  2482. setsockopt(FD(c), SOL_TCP, TCP_NODELAY, (char *) &on, sizeof(on));
  2483. #if defined(TCP_QUICKACK)
  2484. setsockopt(FD(c), SOL_TCP, TCP_QUICKACK, (char *) &on, sizeof(on));
  2485. #endif
  2486. setsockopt(FD(c), SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on));
  2487. #if ESP32 || ESP8266 || defined(__linux__)
  2488. int idle = 60;
  2489. setsockopt(FD(c), IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));
  2490. #endif
  2491. #ifndef _WIN32
  2492. {
  2493. int cnt = 3, intvl = 20;
  2494. setsockopt(FD(c), IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));
  2495. setsockopt(FD(c), IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl));
  2496. }
  2497. #endif
  2498. #endif
  2499. }
  2500. void mg_connect_resolved(struct mg_connection *c) {
  2501. char buf[40];
  2502. int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
  2503. int af = AF_INET;
  2504. #if MG_ENABLE_IPV6
  2505. if (c->peer.is_ip6) af = AF_INET6;
  2506. #endif
  2507. mg_straddr(c, buf, sizeof(buf));
  2508. c->fd = (void *) (long) socket(af, type, 0);
  2509. if (FD(c) == INVALID_SOCKET) {
  2510. mg_error(c, "socket(): %d", MG_SOCK_ERRNO);
  2511. return;
  2512. }
  2513. mg_set_non_blocking_mode(FD(c));
  2514. mg_call(c, MG_EV_RESOLVE, NULL);
  2515. if (type == SOCK_STREAM) {
  2516. union usa usa = tousa(&c->peer);
  2517. socklen_t slen =
  2518. #if MG_ENABLE_IPV6
  2519. c->peer.is_ip6 ? sizeof(usa.sin6) :
  2520. #endif
  2521. sizeof(usa.sin);
  2522. int rc = connect(FD(c), &usa.sa, slen);
  2523. int fail = rc < 0 && mg_sock_failed() ? MG_SOCK_ERRNO : 0;
  2524. if (fail) {
  2525. mg_error(c, "connect: %d", MG_SOCK_ERRNO);
  2526. } else {
  2527. setsockopts(c);
  2528. }
  2529. if (rc < 0) c->is_connecting = 1;
  2530. }
  2531. }
  2532. struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
  2533. mg_event_handler_t fn, void *fn_data) {
  2534. struct mg_connection *c = NULL;
  2535. if ((c = alloc_conn(mgr, 1, INVALID_SOCKET)) == NULL) {
  2536. LOG(LL_ERROR, ("OOM"));
  2537. } else {
  2538. struct mg_str host = mg_url_host(url);
  2539. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  2540. c->is_udp = (strncmp(url, "udp:", 4) == 0);
  2541. c->peer.port = mg_htons(mg_url_port(url));
  2542. c->fn = fn;
  2543. c->fn_data = fn_data;
  2544. LOG(LL_DEBUG, ("%lu -> %s", c->id, url));
  2545. mg_resolve(c, &host, mgr->dnstimeout);
  2546. }
  2547. return c;
  2548. }
  2549. static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
  2550. struct mg_connection *c = NULL;
  2551. union usa usa;
  2552. socklen_t sa_len = sizeof(usa);
  2553. SOCKET fd = accept(FD(lsn), &usa.sa, &sa_len);
  2554. if (fd == INVALID_SOCKET) {
  2555. LOG(LL_ERROR, ("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
  2556. #if !defined(_WIN32)
  2557. } else if (fd >= FD_SETSIZE) {
  2558. LOG(LL_ERROR, ("%ld > %ld", (long) fd, (long) FD_SETSIZE));
  2559. closesocket(fd);
  2560. #endif
  2561. } else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
  2562. LOG(LL_ERROR, ("%lu OOM", lsn->id));
  2563. closesocket(fd);
  2564. } else {
  2565. char buf[40];
  2566. c->peer.port = usa.sin.sin_port;
  2567. memcpy(&c->peer.ip, &usa.sin.sin_addr, sizeof(c->peer.ip));
  2568. #if MG_ENABLE_IPV6
  2569. if (sa_len == sizeof(usa.sin6)) {
  2570. memcpy(c->peer.ip6, &usa.sin6.sin6_addr, sizeof(c->peer.ip6));
  2571. c->peer.port = usa.sin6.sin6_port;
  2572. c->peer.is_ip6 = 1;
  2573. }
  2574. #endif
  2575. mg_straddr(c, buf, sizeof(buf));
  2576. LOG(LL_DEBUG, ("%lu accepted %s", c->id, buf));
  2577. mg_set_non_blocking_mode(FD(c));
  2578. setsockopts(c);
  2579. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  2580. c->is_accepted = 1;
  2581. c->is_hexdumping = lsn->is_hexdumping;
  2582. c->pfn = lsn->pfn;
  2583. c->pfn_data = lsn->pfn_data;
  2584. c->fn = lsn->fn;
  2585. c->fn_data = lsn->fn_data;
  2586. mg_call(c, MG_EV_ACCEPT, NULL);
  2587. }
  2588. }
  2589. #if MG_ENABLE_SOCKETPAIR
  2590. bool mg_socketpair(int *s1, int *s2) {
  2591. #ifdef MG_ENABLE_NATIVE_SOCKETPAIR
  2592. // For some reason, native socketpair() call fails on Macos
  2593. // Enable this codepath only when MG_ENABLE_NATIVE_SOCKETPAIR is defined
  2594. int sp[2], ret = 0;
  2595. if (socketpair(AF_INET, SOCK_DGRAM, IPPROTO_UDP, sp) == 0) {
  2596. *s1 = sp[0], *s2 = sp[1], ret = 1;
  2597. }
  2598. LOG(LL_INFO, ("errno %d", errno));
  2599. return ret;
  2600. #else
  2601. union usa sa, sa2;
  2602. SOCKET sp[2] = {INVALID_SOCKET, INVALID_SOCKET};
  2603. socklen_t len = sizeof(sa.sin);
  2604. int ret = 0;
  2605. (void) memset(&sa, 0, sizeof(sa));
  2606. sa.sin.sin_family = AF_INET;
  2607. sa.sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
  2608. sa2 = sa;
  2609. if ((sp[0] = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET &&
  2610. (sp[1] = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET &&
  2611. bind(sp[0], &sa.sa, len) == 0 && bind(sp[1], &sa2.sa, len) == 0 &&
  2612. getsockname(sp[0], &sa.sa, &len) == 0 &&
  2613. getsockname(sp[1], &sa2.sa, &len) == 0 &&
  2614. connect(sp[0], &sa2.sa, len) == 0 && connect(sp[1], &sa.sa, len) == 0) {
  2615. mg_set_non_blocking_mode(sp[1]);
  2616. *s1 = sp[0];
  2617. *s2 = sp[1];
  2618. ret = 1;
  2619. } else {
  2620. if (sp[0] != INVALID_SOCKET) closesocket(sp[0]);
  2621. if (sp[1] != INVALID_SOCKET) closesocket(sp[1]);
  2622. }
  2623. return ret;
  2624. #endif
  2625. }
  2626. #endif
  2627. struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
  2628. mg_event_handler_t fn, void *fn_data) {
  2629. struct mg_connection *c = NULL;
  2630. int is_udp = strncmp(url, "udp:", 4) == 0;
  2631. SOCKET fd = mg_open_listener(url);
  2632. if (fd == INVALID_SOCKET) {
  2633. } else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
  2634. LOG(LL_ERROR, ("OOM %s", url));
  2635. closesocket(fd);
  2636. } else {
  2637. c->fd = (void *) (long) fd;
  2638. c->is_listening = 1;
  2639. c->is_udp = is_udp;
  2640. setsockopts(c);
  2641. LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  2642. c->fn = fn;
  2643. c->fn_data = fn_data;
  2644. LOG(LL_INFO, ("%lu accepting on %s", c->id, url));
  2645. }
  2646. return c;
  2647. }
  2648. static void mg_iotest(struct mg_mgr *mgr, int ms) {
  2649. #if MG_ARCH == MG_ARCH_FREERTOS
  2650. struct mg_connection *c;
  2651. for (c = mgr->conns; c != NULL; c = c->next) {
  2652. FreeRTOS_FD_CLR(c->fd, mgr->ss, eSELECT_WRITE);
  2653. if (c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0))
  2654. FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_WRITE);
  2655. }
  2656. FreeRTOS_select(mgr->ss, pdMS_TO_TICKS(ms));
  2657. for (c = mgr->conns; c != NULL; c = c->next) {
  2658. EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss);
  2659. c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1 : 0;
  2660. c->is_writable = bits & eSELECT_WRITE ? 1 : 0;
  2661. }
  2662. #else
  2663. struct timeval tv = {ms / 1000, (ms % 1000) * 1000};
  2664. struct mg_connection *c;
  2665. fd_set rset, wset;
  2666. SOCKET maxfd = 0;
  2667. int rc;
  2668. FD_ZERO(&rset);
  2669. FD_ZERO(&wset);
  2670. for (c = mgr->conns; c != NULL; c = c->next) {
  2671. // c->is_writable = 0;
  2672. // TLS might have stuff buffered, so dig everything
  2673. // c->is_readable = c->is_tls && c->is_readable ? 1 : 0;
  2674. if (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) continue;
  2675. FD_SET(FD(c), &rset);
  2676. if (FD(c) > maxfd) maxfd = FD(c);
  2677. if (c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0))
  2678. FD_SET(FD(c), &wset);
  2679. }
  2680. if ((rc = select(maxfd + 1, &rset, &wset, NULL, &tv)) < 0) {
  2681. LOG(LL_DEBUG, ("select: %d %d", rc, MG_SOCK_ERRNO));
  2682. FD_ZERO(&rset);
  2683. FD_ZERO(&wset);
  2684. }
  2685. for (c = mgr->conns; c != NULL; c = c->next) {
  2686. // TLS might have stuff buffered, so dig everything
  2687. c->is_readable = c->is_tls && c->is_readable
  2688. ? 1
  2689. : FD(c) != INVALID_SOCKET && FD_ISSET(FD(c), &rset);
  2690. c->is_writable = FD(c) != INVALID_SOCKET && FD_ISSET(FD(c), &wset);
  2691. }
  2692. #endif
  2693. }
  2694. static void connect_conn(struct mg_connection *c) {
  2695. int rc = 0;
  2696. socklen_t len = sizeof(rc);
  2697. if (getsockopt(FD(c), SOL_SOCKET, SO_ERROR, (char *) &rc, &len)) rc = 1;
  2698. if (rc == EAGAIN || rc == EWOULDBLOCK) rc = 0;
  2699. c->is_connecting = 0;
  2700. if (rc) {
  2701. char buf[40];
  2702. mg_error(c, "error connecting to %s", mg_straddr(c, buf, sizeof(buf)));
  2703. } else {
  2704. if (c->is_tls_hs) mg_tls_handshake(c);
  2705. mg_call(c, MG_EV_CONNECT, NULL);
  2706. }
  2707. }
  2708. void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
  2709. struct mg_connection *c, *tmp;
  2710. unsigned long now;
  2711. mg_iotest(mgr, ms);
  2712. now = mg_millis();
  2713. mg_timer_poll(now);
  2714. for (c = mgr->conns; c != NULL; c = tmp) {
  2715. tmp = c->next;
  2716. mg_call(c, MG_EV_POLL, &now);
  2717. LOG(LL_VERBOSE_DEBUG,
  2718. ("%lu %c%c %c%c%c%c%c", c->id, c->is_readable ? 'r' : '-',
  2719. c->is_writable ? 'w' : '-', c->is_tls ? 'T' : 't',
  2720. c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
  2721. c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
  2722. if (c->is_resolving || c->is_closing) {
  2723. // Do nothing
  2724. } else if (c->is_listening && c->is_udp == 0) {
  2725. if (c->is_readable) accept_conn(mgr, c);
  2726. } else if (c->is_connecting) {
  2727. if (c->is_readable || c->is_writable) connect_conn(c);
  2728. } else if (c->is_tls_hs) {
  2729. if ((c->is_readable || c->is_writable)) mg_tls_handshake(c);
  2730. } else {
  2731. if (c->is_readable) read_conn(c, ll_read);
  2732. if (c->is_writable) write_conn(c);
  2733. }
  2734. if (c->is_draining && c->send.len == 0) c->is_closing = 1;
  2735. if (c->is_closing) close_conn(c);
  2736. }
  2737. }
  2738. #endif
  2739. #ifdef MG_ENABLE_LINES
  2740. #line 1 "src/ssi.c"
  2741. #endif
  2742. #ifndef MG_MAX_SSI_DEPTH
  2743. #define MG_MAX_SSI_DEPTH 5
  2744. #endif
  2745. #if MG_ENABLE_SSI
  2746. static char *mg_ssi(const char *path, const char *root, int depth) {
  2747. struct mg_iobuf b = {NULL, 0, 0};
  2748. FILE *fp = fopen(path, "rb");
  2749. if (fp != NULL) {
  2750. char buf[BUFSIZ], arg[sizeof(buf)];
  2751. int ch, intag = 0;
  2752. size_t len = 0, align = MG_IO_SIZE;
  2753. while ((ch = fgetc(fp)) != EOF) {
  2754. if (intag && ch == '>' && buf[len - 1] == '-' && buf[len - 2] == '-') {
  2755. buf[len++] = ch & 0xff;
  2756. if (sscanf(buf, "<!--#include file=\"%[^\"]", arg)) {
  2757. char tmp[PATH_MAX], *p = (char *) path + strlen(path), *data;
  2758. while (p > path && p[-1] != MG_DIRSEP && p[-1] != '/') p--;
  2759. snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
  2760. if (depth < MG_MAX_SSI_DEPTH &&
  2761. (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
  2762. mg_iobuf_append(&b, data, strlen(data), align);
  2763. free(data);
  2764. } else {
  2765. LOG(LL_ERROR, ("%s: file=%s error or too deep", path, arg));
  2766. }
  2767. } else if (sscanf(buf, "<!--#include virtual=\"%[^\"]", arg)) {
  2768. char tmp[PATH_MAX], *data;
  2769. snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
  2770. if (depth < MG_MAX_SSI_DEPTH &&
  2771. (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
  2772. mg_iobuf_append(&b, data, strlen(data), align);
  2773. free(data);
  2774. } else {
  2775. LOG(LL_ERROR, ("%s: virtual=%s error or too deep", path, arg));
  2776. }
  2777. } else {
  2778. // Unknown SSI tag
  2779. LOG(LL_INFO, ("Unknown SSI tag: %.*s", (int) len, buf));
  2780. mg_iobuf_append(&b, buf, len, align);
  2781. }
  2782. intag = 0;
  2783. len = 0;
  2784. } else if (ch == '<') {
  2785. intag = 1;
  2786. if (len > 0) mg_iobuf_append(&b, buf, len, align);
  2787. len = 0;
  2788. buf[len++] = ch & 0xff;
  2789. } else if (intag) {
  2790. if (len == 5 && strncmp(buf, "<!--#", 5) != 0) {
  2791. intag = 0;
  2792. } else if (len >= sizeof(buf) - 2) {
  2793. LOG(LL_ERROR, ("%s: SSI tag is too large", path));
  2794. len = 0;
  2795. }
  2796. buf[len++] = ch & 0xff;
  2797. } else {
  2798. buf[len++] = ch & 0xff;
  2799. if (len >= sizeof(buf)) {
  2800. mg_iobuf_append(&b, buf, len, align);
  2801. len = 0;
  2802. }
  2803. }
  2804. }
  2805. if (len > 0) mg_iobuf_append(&b, buf, len, align);
  2806. if (b.len > 0) mg_iobuf_append(&b, "", 1, align); // nul-terminate
  2807. fclose(fp);
  2808. }
  2809. (void) depth;
  2810. (void) root;
  2811. return (char *) b.buf;
  2812. }
  2813. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  2814. const char *fullpath) {
  2815. char *data = mg_ssi(fullpath, root, 0);
  2816. mg_http_reply(c, 200, "", "%s", data == NULL ? "" : data);
  2817. free(data);
  2818. }
  2819. #endif
  2820. #ifdef MG_ENABLE_LINES
  2821. #line 1 "src/str.c"
  2822. #endif
  2823. #include <stdlib.h>
  2824. struct mg_str mg_str(const char *s) {
  2825. struct mg_str str = {s, s == NULL ? 0 : strlen(s)};
  2826. return str;
  2827. }
  2828. struct mg_str mg_str_n(const char *s, size_t n) {
  2829. struct mg_str str = {s, n};
  2830. return str;
  2831. }
  2832. int mg_lower(const char *s) {
  2833. return tolower(*(const unsigned char *) s);
  2834. }
  2835. int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
  2836. int diff = 0;
  2837. if (len > 0) do {
  2838. diff = mg_lower(s1++) - mg_lower(s2++);
  2839. } while (diff == 0 && s1[-1] != '\0' && --len > 0);
  2840. return diff;
  2841. }
  2842. int mg_casecmp(const char *s1, const char *s2) {
  2843. return mg_ncasecmp(s1, s2, (size_t) ~0);
  2844. }
  2845. int mg_vcmp(const struct mg_str *s1, const char *s2) {
  2846. size_t n2 = strlen(s2), n1 = s1->len;
  2847. int r = strncmp(s1->ptr, s2, (n1 < n2) ? n1 : n2);
  2848. if (r == 0) return (int) (n1 - n2);
  2849. return r;
  2850. }
  2851. int mg_vcasecmp(const struct mg_str *str1, const char *str2) {
  2852. size_t n2 = strlen(str2), n1 = str1->len;
  2853. int r = mg_ncasecmp(str1->ptr, str2, (n1 < n2) ? n1 : n2);
  2854. if (r == 0) return (int) (n1 - n2);
  2855. return r;
  2856. }
  2857. struct mg_str mg_strdup(const struct mg_str s) {
  2858. struct mg_str r = {NULL, 0};
  2859. if (s.len > 0 && s.ptr != NULL) {
  2860. char *sc = (char *) malloc(s.len + 1);
  2861. if (sc != NULL) {
  2862. memcpy(sc, s.ptr, s.len);
  2863. sc[s.len] = '\0';
  2864. r.ptr = sc;
  2865. r.len = s.len;
  2866. }
  2867. }
  2868. return r;
  2869. }
  2870. int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
  2871. size_t i = 0;
  2872. while (i < str1.len && i < str2.len) {
  2873. int c1 = str1.ptr[i];
  2874. int c2 = str2.ptr[i];
  2875. if (c1 < c2) return -1;
  2876. if (c1 > c2) return 1;
  2877. i++;
  2878. }
  2879. if (i < str1.len) return 1;
  2880. if (i < str2.len) return -1;
  2881. return 0;
  2882. }
  2883. const char *mg_strstr(const struct mg_str haystack,
  2884. const struct mg_str needle) {
  2885. size_t i;
  2886. if (needle.len > haystack.len) return NULL;
  2887. for (i = 0; i <= haystack.len - needle.len; i++) {
  2888. if (memcmp(haystack.ptr + i, needle.ptr, needle.len) == 0) {
  2889. return haystack.ptr + i;
  2890. }
  2891. }
  2892. return NULL;
  2893. }
  2894. struct mg_str mg_strstrip(struct mg_str s) {
  2895. while (s.len > 0 && isspace((int) *s.ptr)) s.ptr++, s.len--;
  2896. while (s.len > 0 && isspace((int) *(s.ptr + s.len - 1))) s.len--;
  2897. return s;
  2898. }
  2899. #ifdef MG_ENABLE_LINES
  2900. #line 1 "src/timer.c"
  2901. #endif
  2902. // Copyright (c) Cesanta Software Limited
  2903. // All rights reserved
  2904. struct mg_timer *g_timers;
  2905. void mg_timer_init(struct mg_timer *t, int ms, int flags, void (*fn)(void *),
  2906. void *arg) {
  2907. struct mg_timer tmp = {ms, flags, fn, arg, 0UL, g_timers};
  2908. *t = tmp;
  2909. g_timers = t;
  2910. if (flags & MG_TIMER_RUN_NOW) fn(arg);
  2911. }
  2912. void mg_timer_free(struct mg_timer *t) {
  2913. struct mg_timer **head = &g_timers;
  2914. while (*head && *head != t) head = &(*head)->next;
  2915. if (*head) *head = t->next;
  2916. }
  2917. void mg_timer_poll(unsigned long now_ms) {
  2918. // If time goes back (wrapped around), reset timers
  2919. struct mg_timer *t, *tmp;
  2920. static unsigned long oldnow; // Timestamp in a previous invocation
  2921. if (oldnow > now_ms) { // If it is wrapped, reset timers
  2922. for (t = g_timers; t != NULL; t = t->next) t->expire = 0;
  2923. }
  2924. oldnow = now_ms;
  2925. for (t = g_timers; t != NULL; t = tmp) {
  2926. tmp = t->next;
  2927. if (t->expire == 0) t->expire = now_ms + t->period_ms;
  2928. if (t->expire > now_ms) continue;
  2929. t->fn(t->arg);
  2930. // Try to tick timers with the given period as accurate as possible,
  2931. // even if this polling function is called with some random period.
  2932. t->expire = now_ms - t->expire > (unsigned long) t->period_ms
  2933. ? now_ms + t->period_ms
  2934. : t->expire + t->period_ms;
  2935. if (!(t->flags & MG_TIMER_REPEAT)) mg_timer_free(t);
  2936. }
  2937. }
  2938. #ifdef MG_ENABLE_LINES
  2939. #line 1 "src/tls.c"
  2940. #endif
  2941. #if MG_ENABLE_MBEDTLS ///////////////////////////////////////// MBEDTLS
  2942. #include <mbedtls/debug.h>
  2943. #include <mbedtls/ssl.h>
  2944. #ifndef EXTERN_C
  2945. #ifdef __cplusplus
  2946. #define EXTERN_C extern "C"
  2947. #else
  2948. #define EXTERN_C
  2949. #endif
  2950. #endif
  2951. // Different versions have those in different files, so declare here
  2952. EXTERN_C int mbedtls_net_recv(void *, unsigned char *, size_t);
  2953. EXTERN_C int mbedtls_net_send(void *, const unsigned char *, size_t);
  2954. struct mg_tls {
  2955. char *cafile; // CA certificate path
  2956. mbedtls_x509_crt ca; // Parsed CA certificate
  2957. mbedtls_x509_crt cert; // Parsed certificate
  2958. mbedtls_ssl_context ssl; // SSL/TLS context
  2959. mbedtls_ssl_config conf; // SSL-TLS config
  2960. mbedtls_pk_context pk; // Private key context
  2961. };
  2962. int mg_tls_handshake(struct mg_connection *c) {
  2963. struct mg_tls *tls = (struct mg_tls *) c->tls;
  2964. int rc;
  2965. mbedtls_ssl_set_bio(&tls->ssl, &c->fd, mbedtls_net_send, mbedtls_net_recv, 0);
  2966. rc = mbedtls_ssl_handshake(&tls->ssl);
  2967. if (rc == 0) { // Success
  2968. LOG(LL_DEBUG, ("%lu success", c->id));
  2969. c->is_tls_hs = 0;
  2970. } else if (rc == MBEDTLS_ERR_SSL_WANT_READ ||
  2971. rc == MBEDTLS_ERR_SSL_WANT_WRITE) { // Still pending
  2972. LOG(LL_VERBOSE_DEBUG, ("%lu pending, %d%d %d (-%#x)", c->id,
  2973. c->is_connecting, c->is_tls_hs, rc, -rc));
  2974. } else {
  2975. mg_error(c, "TLS handshake: -%#x", -rc); // Error
  2976. }
  2977. return rc == 0;
  2978. }
  2979. static int mbed_rng(void *ctx, unsigned char *buf, size_t len) {
  2980. mg_random(buf, len);
  2981. (void) ctx;
  2982. return 0;
  2983. }
  2984. static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) {
  2985. n = strlen(s2) - 1;
  2986. LOG(LL_VERBOSE_DEBUG, ("%p %.*s", ((struct mg_connection *) c)->fd, n, s2));
  2987. (void) s;
  2988. (void) c;
  2989. (void) lev;
  2990. }
  2991. int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
  2992. struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
  2993. int rc = 0;
  2994. if (tls == NULL) {
  2995. mg_error(c, "TLS OOM");
  2996. goto fail;
  2997. }
  2998. LOG(LL_DEBUG, ("%lu Setting TLS, CA: %s, cert: %s, key: %s", c->id,
  2999. opts->ca == NULL ? "null" : opts->ca,
  3000. opts->cert == NULL ? "null" : opts->cert,
  3001. opts->certkey == NULL ? "null" : opts->certkey));
  3002. mbedtls_ssl_init(&tls->ssl);
  3003. mbedtls_ssl_config_init(&tls->conf);
  3004. mbedtls_ssl_conf_dbg(&tls->conf, debug_cb, c);
  3005. #if !defined(ESP_PLATFORM)
  3006. mbedtls_debug_set_threshold(5);
  3007. #endif
  3008. if ((rc = mbedtls_ssl_config_defaults(
  3009. &tls->conf,
  3010. c->is_client ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
  3011. MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
  3012. mg_error(c, "tls defaults %#x", -rc);
  3013. goto fail;
  3014. }
  3015. mbedtls_ssl_conf_rng(&tls->conf, mbed_rng, c);
  3016. if (opts->ca == NULL || strcmp(opts->ca, "*") == 0) {
  3017. mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
  3018. }
  3019. if (opts->ca != NULL && opts->ca[0] != '\0') {
  3020. #if defined(MBEDTLS_X509_CA_CHAIN_ON_DISK)
  3021. tls->cafile = strdup(opts->ca);
  3022. rc = mbedtls_ssl_conf_ca_chain_file(&tls->conf, tls->cafile, NULL);
  3023. if (rc != 0) {
  3024. mg_error(c, "parse on-disk chain(%s) err %#x", opts->ca, -rc);
  3025. goto fail;
  3026. }
  3027. #else
  3028. mbedtls_x509_crt_init(&tls->ca);
  3029. if ((rc = mbedtls_x509_crt_parse_file(&tls->ca, opts->ca)) != 0) {
  3030. mg_error(c, "parse(%s) err %#x", opts->ca, -rc);
  3031. goto fail;
  3032. }
  3033. mbedtls_ssl_conf_ca_chain(&tls->conf, &tls->ca, NULL);
  3034. #endif
  3035. mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
  3036. }
  3037. if (opts->cert != NULL && opts->cert[0] != '\0') {
  3038. const char *key = opts->certkey;
  3039. if (key == NULL) key = opts->cert;
  3040. mbedtls_x509_crt_init(&tls->cert);
  3041. mbedtls_pk_init(&tls->pk);
  3042. if ((rc = mbedtls_x509_crt_parse_file(&tls->cert, opts->cert)) != 0) {
  3043. mg_error(c, "parse(%s) err %#x", opts->cert, -rc);
  3044. goto fail;
  3045. }
  3046. if ((rc = mbedtls_pk_parse_keyfile(&tls->pk, key, NULL)) != 0) {
  3047. mg_error(c, "tls key(%s) %#x", key, -rc);
  3048. goto fail;
  3049. }
  3050. rc = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->cert, &tls->pk);
  3051. if (rc != 0) {
  3052. mg_error(c, "own cert %#x", -rc);
  3053. goto fail;
  3054. }
  3055. }
  3056. if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) {
  3057. mg_error(c, "setup err %#x", -rc);
  3058. goto fail;
  3059. }
  3060. c->tls = tls;
  3061. c->is_tls = 1;
  3062. c->is_tls_hs = 1;
  3063. if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
  3064. mg_tls_handshake(c);
  3065. }
  3066. return 1;
  3067. fail:
  3068. c->is_closing = 1;
  3069. free(tls);
  3070. return 0;
  3071. }
  3072. int mg_tls_recv(struct mg_connection *c, void *buf, size_t len, int *fail) {
  3073. struct mg_tls *tls = (struct mg_tls *) c->tls;
  3074. int n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
  3075. *fail = (n == 0) || (n < 0 && n != MBEDTLS_ERR_SSL_WANT_READ);
  3076. return n;
  3077. }
  3078. int mg_tls_send(struct mg_connection *c, const void *buf, size_t len,
  3079. int *fail) {
  3080. struct mg_tls *tls = (struct mg_tls *) c->tls;
  3081. int n = mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len);
  3082. *fail = (n == 0) || (n < 0 && n != MBEDTLS_ERR_SSL_WANT_WRITE);
  3083. return n;
  3084. }
  3085. int mg_tls_free(struct mg_connection *c) {
  3086. struct mg_tls *tls = (struct mg_tls *) c->tls;
  3087. if (tls == NULL) return 0;
  3088. free(tls->cafile);
  3089. mbedtls_x509_crt_free(&tls->ca);
  3090. mbedtls_x509_crt_free(&tls->cert);
  3091. mbedtls_ssl_free(&tls->ssl);
  3092. mbedtls_pk_free(&tls->pk);
  3093. mbedtls_ssl_config_free(&tls->conf);
  3094. free(tls);
  3095. return 1;
  3096. }
  3097. #elif MG_ENABLE_OPENSSL ///////////////////////////////////////// OPENSSL
  3098. #include <openssl/err.h>
  3099. #include <openssl/ssl.h>
  3100. struct mg_tls {
  3101. SSL_CTX *ctx;
  3102. SSL *ssl;
  3103. };
  3104. static int mg_tls_err(struct mg_tls *tls, int res) {
  3105. int err = SSL_get_error(tls->ssl, res);
  3106. // We've just fetched the last error from the queue.
  3107. // Now we need to clear the error queue. If we do not, then the following
  3108. // can happen (actually reported):
  3109. // - A new connection is accept()-ed with cert error (e.g. self-signed cert)
  3110. // - Since all accept()-ed connections share listener's context,
  3111. // - *ALL* SSL accepted connection report read error on the next poll cycle.
  3112. // Thus a single errored connection can close all the rest, unrelated ones.
  3113. // Clearing the error keeps the shared SSL_CTX in an OK state.
  3114. ERR_clear_error();
  3115. if (err == SSL_ERROR_WANT_READ) return 0;
  3116. if (err == SSL_ERROR_WANT_WRITE) return 0;
  3117. return err;
  3118. }
  3119. int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
  3120. struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
  3121. const char *id = "mongoose";
  3122. static unsigned char s_initialised = 0;
  3123. int rc;
  3124. if (tls == NULL) {
  3125. mg_error(c, "TLS OOM");
  3126. goto fail;
  3127. }
  3128. if (!s_initialised) {
  3129. SSL_library_init();
  3130. s_initialised++;
  3131. }
  3132. LOG(LL_DEBUG, ("%lu Setting TLS, CA: %s, cert: %s, key: %s", c->id,
  3133. opts->ca == NULL ? "null" : opts->ca,
  3134. opts->cert == NULL ? "null" : opts->cert,
  3135. opts->certkey == NULL ? "null" : opts->certkey));
  3136. tls->ctx = c->is_client ? SSL_CTX_new(SSLv23_client_method())
  3137. : SSL_CTX_new(SSLv23_server_method());
  3138. if ((tls->ssl = SSL_new(tls->ctx)) == NULL) {
  3139. mg_error(c, "SSL_new");
  3140. goto fail;
  3141. }
  3142. SSL_set_session_id_context(tls->ssl, (const uint8_t *) id, strlen(id));
  3143. // Disable deprecated protocols
  3144. SSL_set_options(tls->ssl, SSL_OP_NO_SSLv2);
  3145. SSL_set_options(tls->ssl, SSL_OP_NO_SSLv3);
  3146. SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1);
  3147. #ifdef MG_ENABLE_OPENSSL_NO_COMPRESSION
  3148. SSL_set_options(tls->ssl, SSL_OP_NO_COMPRESSION);
  3149. #endif
  3150. #ifdef MG_ENABLE_OPENSSL_CIPHER_SERVER_PREFERENCE
  3151. SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
  3152. #endif
  3153. SSL_set_verify(tls->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
  3154. 0);
  3155. if (opts->ca != NULL && opts->ca[0] != '\0') {
  3156. if ((rc = SSL_CTX_load_verify_locations(tls->ctx, opts->ca, NULL)) != 1) {
  3157. mg_error(c, "parse(%s): err %d", opts->ca, mg_tls_err(tls, rc));
  3158. goto fail;
  3159. }
  3160. }
  3161. if (opts->cert != NULL && opts->cert[0] != '\0') {
  3162. const char *key = opts->certkey;
  3163. if (key == NULL) key = opts->cert;
  3164. if ((rc = SSL_use_certificate_file(tls->ssl, opts->cert, 1)) != 1) {
  3165. mg_error(c, "Invalid SSL cert, err %d", mg_tls_err(tls, rc));
  3166. goto fail;
  3167. } else if ((rc = SSL_use_PrivateKey_file(tls->ssl, key, 1)) != 1) {
  3168. mg_error(c, "Invalid SSL key, err %d", mg_tls_err(tls, rc));
  3169. goto fail;
  3170. #if OPENSSL_VERSION_NUMBER > 0x10002000L
  3171. } else if ((rc = SSL_use_certificate_chain_file(tls->ssl, opts->cert)) !=
  3172. 1) {
  3173. mg_error(c, "Invalid CA, err %d", mg_tls_err(tls, rc));
  3174. goto fail;
  3175. #endif
  3176. } else {
  3177. SSL_set_mode(tls->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  3178. #if OPENSSL_VERSION_NUMBER > 0x10002000L
  3179. SSL_set_ecdh_auto(tls->ssl, 1);
  3180. #endif
  3181. }
  3182. }
  3183. if (opts->ciphers != NULL) SSL_set_cipher_list(tls->ssl, opts->ciphers);
  3184. if (opts->srvname != NULL) SSL_set_tlsext_host_name(tls->ssl, opts->srvname);
  3185. c->tls = tls;
  3186. c->is_tls = 1;
  3187. c->is_tls_hs = 1;
  3188. if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
  3189. mg_tls_handshake(c);
  3190. }
  3191. c->is_hexdumping = 1;
  3192. LOG(LL_DEBUG, ("%lu SSL %s OK", c->id, c->is_accepted ? "accept" : "client"));
  3193. return 1;
  3194. fail:
  3195. c->is_closing = 1;
  3196. free(tls);
  3197. return 0;
  3198. }
  3199. int mg_tls_handshake(struct mg_connection *c) {
  3200. struct mg_tls *tls = (struct mg_tls *) c->tls;
  3201. int rc;
  3202. SSL_set_fd(tls->ssl, (long) c->fd);
  3203. rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl);
  3204. if (rc == 1) {
  3205. LOG(LL_DEBUG, ("%lu success", c->id));
  3206. c->is_tls_hs = 0;
  3207. return 1;
  3208. } else {
  3209. int code;
  3210. ERR_print_errors_fp(stderr);
  3211. code = mg_tls_err(tls, rc);
  3212. if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
  3213. return 0;
  3214. }
  3215. }
  3216. int mg_tls_free(struct mg_connection *c) {
  3217. struct mg_tls *tls = (struct mg_tls *) c->tls;
  3218. if (tls == NULL) return 0;
  3219. SSL_free(tls->ssl);
  3220. SSL_CTX_free(tls->ctx);
  3221. free(tls);
  3222. return 1;
  3223. }
  3224. int mg_tls_recv(struct mg_connection *c, void *buf, size_t len, int *fail) {
  3225. struct mg_tls *tls = (struct mg_tls *) c->tls;
  3226. int n = SSL_read(tls->ssl, buf, len);
  3227. *fail = (n == 0) || (n < 0 && mg_tls_err(tls, n) != 0);
  3228. return n;
  3229. }
  3230. int mg_tls_send(struct mg_connection *c, const void *buf, size_t len,
  3231. int *fail) {
  3232. struct mg_tls *tls = (struct mg_tls *) c->tls;
  3233. int n = SSL_write(tls->ssl, buf, len);
  3234. *fail = (n == 0) || (n < 0 && mg_tls_err(tls, n) != 0);
  3235. return n;
  3236. }
  3237. #else ////////////////////////////////////////// NO TLS
  3238. int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
  3239. (void) opts;
  3240. mg_error(c, "TLS is not enabled");
  3241. return 0;
  3242. }
  3243. int mg_tls_handshake(struct mg_connection *c) {
  3244. return c != NULL;
  3245. }
  3246. int mg_tls_free(struct mg_connection *c) {
  3247. return c != NULL;
  3248. }
  3249. int mg_tls_recv(struct mg_connection *c, void *buf, size_t len, int *fail) {
  3250. *fail = 1;
  3251. return c == NULL || buf == NULL || len == 0 ? 0 : -1;
  3252. }
  3253. int mg_tls_send(struct mg_connection *c, const void *buf, size_t len,
  3254. int *fail) {
  3255. *fail = 1;
  3256. return c == NULL || buf == NULL || len == 0 ? 0 : -1;
  3257. }
  3258. #endif
  3259. #ifdef MG_ENABLE_LINES
  3260. #line 1 "src/url.c"
  3261. #endif
  3262. #include <stdlib.h>
  3263. struct url {
  3264. int key, user, pass, host, port, uri, end;
  3265. };
  3266. int mg_url_is_ssl(const char *url) {
  3267. return strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0 ||
  3268. strncmp(url, "mqtts:", 6) == 0 || strncmp(url, "ssl:", 4) == 0 ||
  3269. strncmp(url, "tls:", 4) == 0;
  3270. }
  3271. static struct url urlparse(const char *url) {
  3272. int i;
  3273. struct url u;
  3274. memset(&u, 0, sizeof(u));
  3275. for (i = 0; url[i] != '\0'; i++) {
  3276. if (i > 0 && url[i - 1] == '/' && url[i] == '/') {
  3277. u.host = i + 1;
  3278. u.port = 0;
  3279. } else if (url[i] == ']') {
  3280. u.port = 0; // IPv6 URLs, like http://[::1]/bar
  3281. } else if (url[i] == ':') {
  3282. u.port = i + 1;
  3283. } else if (url[i] == '@') {
  3284. u.user = u.host;
  3285. u.pass = u.port;
  3286. u.host = i + 1;
  3287. u.port = 0;
  3288. } else if (u.host && !u.uri && url[i] == '/') {
  3289. u.uri = i;
  3290. }
  3291. }
  3292. u.end = i;
  3293. #if 0
  3294. printf("[%s] %d %d %d %d %d\n", url, u.user, u.pass, u.host, u.port, u.uri);
  3295. #endif
  3296. return u;
  3297. }
  3298. struct mg_str mg_url_host(const char *url) {
  3299. struct url u = urlparse(url);
  3300. int n =
  3301. u.port ? u.port - u.host - 1 : u.uri ? u.uri - u.host : u.end - u.host;
  3302. struct mg_str s = mg_str_n(url + u.host, n);
  3303. if (s.len > 2 && s.ptr[0] == '[' && s.ptr[s.len - 1] == ']') {
  3304. s.len -= 2;
  3305. s.ptr++;
  3306. }
  3307. return s;
  3308. }
  3309. const char *mg_url_uri(const char *url) {
  3310. struct url u = urlparse(url);
  3311. return u.uri ? url + u.uri : "/";
  3312. }
  3313. unsigned short mg_url_port(const char *url) {
  3314. struct url u = urlparse(url);
  3315. unsigned short port = 0;
  3316. if (memcmp(url, "http:", 5) == 0 || memcmp(url, "ws:", 3) == 0) port = 80;
  3317. if (memcmp(url, "wss:", 4) == 0 || memcmp(url, "https:", 6) == 0) port = 443;
  3318. if (memcmp(url, "mqtt:", 5) == 0) port = 1883;
  3319. if (memcmp(url, "mqtts:", 6) == 0) port = 8883;
  3320. if (u.port) port = atoi(url + u.port);
  3321. return port;
  3322. }
  3323. struct mg_str mg_url_user(const char *url) {
  3324. struct url u = urlparse(url);
  3325. struct mg_str s = mg_str("");
  3326. if (u.user && (u.pass || u.host)) {
  3327. int n = u.pass ? u.pass - u.user - 1 : u.host - u.user - 1;
  3328. s = mg_str_n(url + u.user, n);
  3329. }
  3330. return s;
  3331. }
  3332. struct mg_str mg_url_pass(const char *url) {
  3333. struct url u = urlparse(url);
  3334. struct mg_str s = mg_str("");
  3335. if (u.pass && u.host) {
  3336. int n = u.host - u.pass - 1;
  3337. s = mg_str_n(url + u.pass, n);
  3338. }
  3339. return s;
  3340. }
  3341. #ifdef MG_ENABLE_LINES
  3342. #line 1 "src/util.c"
  3343. #endif
  3344. #if MG_ENABLE_FS
  3345. size_t mg_file_size(const char *path) {
  3346. #if MG_ARCH == MG_ARCH_FREERTOS
  3347. struct FF_STAT st;
  3348. return ff_stat(path, &st) == 0 ? st.st_size : 0;
  3349. #else
  3350. struct stat st;
  3351. return stat(path, &st) == 0 ? st.st_size : 0;
  3352. #endif
  3353. }
  3354. char *mg_file_read(const char *path) {
  3355. FILE *fp;
  3356. char *data = NULL;
  3357. size_t size = mg_file_size(path);
  3358. if ((fp = fopen(path, "rb")) != NULL) {
  3359. data = (char *) malloc(size + 1);
  3360. if (data != NULL) {
  3361. if (fread(data, 1, size, fp) != size) {
  3362. free(data);
  3363. data = NULL;
  3364. } else {
  3365. data[size] = '\0';
  3366. }
  3367. }
  3368. fclose(fp);
  3369. }
  3370. return data;
  3371. }
  3372. bool mg_file_write(const char *path, const void *buf, size_t len) {
  3373. bool result = false;
  3374. FILE *fp;
  3375. char tmp[PATH_MAX];
  3376. snprintf(tmp, sizeof(tmp), "%s.%d", path, rand());
  3377. fp = fopen(tmp, "wb");
  3378. if (fp != NULL) {
  3379. result = fwrite(buf, 1, len, fp) == len;
  3380. fclose(fp);
  3381. if (result) {
  3382. remove(path);
  3383. rename(tmp, path);
  3384. } else {
  3385. remove(tmp);
  3386. }
  3387. }
  3388. return result;
  3389. }
  3390. bool mg_file_printf(const char *path, const char *fmt, ...) {
  3391. char tmp[256], *buf = tmp;
  3392. bool result;
  3393. size_t len;
  3394. va_list ap;
  3395. va_start(ap, fmt);
  3396. len = mg_vasprintf(&buf, sizeof(tmp), fmt, ap);
  3397. va_end(ap);
  3398. result = mg_file_write(path, buf, len);
  3399. if (buf != tmp) free(buf);
  3400. return result;
  3401. }
  3402. void mg_random(void *buf, size_t len) {
  3403. FILE *fp = fopen("/dev/urandom", "rb");
  3404. size_t i, n = 0;
  3405. if (fp != NULL) n = fread(buf, 1, len, fp);
  3406. if (fp == NULL || n <= 0) {
  3407. for (i = 0; i < len; i++) ((unsigned char *) buf)[i] = rand() % 0xff;
  3408. }
  3409. if (fp != NULL) fclose(fp);
  3410. }
  3411. #endif
  3412. bool mg_globmatch(const char *s1, int n1, const char *s2, int n2) {
  3413. int i = 0, j = 0, ni = 0, nj = 0;
  3414. while (i < n1 || j < n2) {
  3415. if (i < n1 && j < n2 && (s1[i] == '?' || s2[j] == s1[i])) {
  3416. i++, j++;
  3417. } else if (i < n1 && (s1[i] == '*' || s1[i] == '#')) {
  3418. ni = i, nj = j + 1, i++;
  3419. } else if (nj > 0 && nj <= n2 && (s1[i - 1] == '#' || s2[j] != '/')) {
  3420. i = ni, j = nj;
  3421. } else {
  3422. return false;
  3423. }
  3424. }
  3425. return true;
  3426. }
  3427. static int mg_nextcommaentry(const char *s, int slen, int ofs, int *koff,
  3428. int *klen, int *voff, int *vlen) {
  3429. int kvlen, kl;
  3430. for (kvlen = 0; ofs + kvlen < slen && s[ofs + kvlen] != ',';) kvlen++;
  3431. for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
  3432. if (koff != NULL) *koff = ofs;
  3433. if (klen != NULL) *klen = kl;
  3434. if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
  3435. if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
  3436. return ofs >= slen ? slen : ofs + kvlen + 1;
  3437. }
  3438. bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
  3439. int koff, klen, voff, vlen;
  3440. int off = mg_nextcommaentry(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen);
  3441. if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
  3442. if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
  3443. *s = mg_str_n(s->ptr + off, s->len - off);
  3444. return off > 0;
  3445. }
  3446. uint32_t mg_ntohl(uint32_t net) {
  3447. uint8_t data[4] = {0, 0, 0, 0};
  3448. memcpy(&data, &net, sizeof(data));
  3449. return ((uint32_t) data[3] << 0) | ((uint32_t) data[2] << 8) |
  3450. ((uint32_t) data[1] << 16) | ((uint32_t) data[0] << 24);
  3451. }
  3452. uint16_t mg_ntohs(uint16_t net) {
  3453. uint8_t data[2] = {0, 0};
  3454. memcpy(&data, &net, sizeof(data));
  3455. return ((uint16_t) data[1] << 0) | ((uint32_t) data[0] << 8);
  3456. }
  3457. char *mg_hexdump(const void *buf, size_t len) {
  3458. const unsigned char *p = (const unsigned char *) buf;
  3459. size_t i, idx, n = 0, ofs = 0, dlen = len * 5 + 100;
  3460. char ascii[17] = "", *dst = (char *) malloc(dlen);
  3461. if (dst == NULL) return dst;
  3462. for (i = 0; i < len; i++) {
  3463. idx = i % 16;
  3464. if (idx == 0) {
  3465. if (i > 0 && dlen > n) n += snprintf(dst + n, dlen - n, " %s\n", ascii);
  3466. if (dlen > n) n += snprintf(dst + n, dlen - n, "%04x ", (int) (i + ofs));
  3467. }
  3468. if (dlen < n) break;
  3469. n += snprintf(dst + n, dlen - n, " %02x", p[i]);
  3470. ascii[idx] = p[i] < 0x20 || p[i] > 0x7e ? '.' : p[i];
  3471. ascii[idx + 1] = '\0';
  3472. }
  3473. while (i++ % 16) {
  3474. if (n < dlen) n += snprintf(dst + n, dlen - n, "%s", " ");
  3475. }
  3476. if (n < dlen) n += snprintf(dst + n, dlen - n, " %s\n", ascii);
  3477. if (n > dlen - 1) n = dlen - 1;
  3478. dst[n] = '\0';
  3479. return dst;
  3480. }
  3481. char *mg_hex(const void *buf, int len, char *to) {
  3482. const unsigned char *p = (const unsigned char *) buf;
  3483. static const char *hex = "0123456789abcdef";
  3484. int i = 0;
  3485. for (; len--; p++) {
  3486. to[i++] = hex[p[0] >> 4];
  3487. to[i++] = hex[p[0] & 0x0f];
  3488. }
  3489. to[i] = '\0';
  3490. return to;
  3491. }
  3492. unsigned long mg_unhexn(const char *s, int len) {
  3493. unsigned long i = 0, v = 0;
  3494. for (i = 0; i < (unsigned long) len; i++) {
  3495. int c = s[i];
  3496. if (i > 0) v <<= 4;
  3497. v |= (c >= '0' && c <= '9') ? c - '0'
  3498. : (c >= 'A' && c <= 'F') ? c - '7' : c - 'W';
  3499. }
  3500. return v;
  3501. }
  3502. void mg_unhex(const char *buf, int len, unsigned char *to) {
  3503. int i;
  3504. for (i = 0; i < len; i += 2) {
  3505. to[i >> 1] = (unsigned char) mg_unhexn(&buf[i], 2);
  3506. }
  3507. }
  3508. int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap) {
  3509. va_list ap_copy;
  3510. int len;
  3511. va_copy(ap_copy, ap);
  3512. len = vsnprintf(*buf, size, fmt, ap_copy);
  3513. va_end(ap_copy);
  3514. if (len < 0) {
  3515. // eCos and Windows are not standard-compliant and return -1 when
  3516. // the buffer is too small. Keep allocating larger buffers until we
  3517. // succeed or out of memory.
  3518. // LCOV_EXCL_START
  3519. *buf = NULL;
  3520. while (len < 0) {
  3521. free(*buf);
  3522. if (size == 0) size = 5;
  3523. size *= 2;
  3524. if ((*buf = (char *) malloc(size)) == NULL) {
  3525. len = -1;
  3526. break;
  3527. }
  3528. va_copy(ap_copy, ap);
  3529. len = vsnprintf(*buf, size - 1, fmt, ap_copy);
  3530. va_end(ap_copy);
  3531. }
  3532. // Microsoft version of vsnprintf() is not always null-terminated, so put
  3533. // the terminator manually
  3534. if (*buf != NULL) (*buf)[len] = 0;
  3535. // LCOV_EXCL_STOP
  3536. } else if (len >= (int) size) {
  3537. /// Standard-compliant code path. Allocate a buffer that is large enough
  3538. if ((*buf = (char *) malloc(len + 1)) == NULL) {
  3539. len = -1; // LCOV_EXCL_LINE
  3540. } else { // LCOV_EXCL_LINE
  3541. va_copy(ap_copy, ap);
  3542. len = vsnprintf(*buf, len + 1, fmt, ap_copy);
  3543. va_end(ap_copy);
  3544. }
  3545. }
  3546. return len;
  3547. }
  3548. int mg_asprintf(char **buf, size_t size, const char *fmt, ...) {
  3549. int ret;
  3550. va_list ap;
  3551. va_start(ap, fmt);
  3552. ret = mg_vasprintf(buf, size, fmt, ap);
  3553. va_end(ap);
  3554. return ret;
  3555. }
  3556. int64_t mg_to64(struct mg_str str) {
  3557. int64_t result = 0, neg = 1;
  3558. size_t i = 0;
  3559. while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
  3560. if (i < str.len && str.ptr[i] == '-') neg = -1, i++;
  3561. while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
  3562. result *= 10;
  3563. result += (str.ptr[i] - '0');
  3564. i++;
  3565. }
  3566. return result * neg;
  3567. }
  3568. double mg_time(void) {
  3569. #if MG_ARCH == MG_ARCH_WIN32
  3570. SYSTEMTIME sysnow;
  3571. FILETIME ftime;
  3572. GetLocalTime(&sysnow);
  3573. SystemTimeToFileTime(&sysnow, &ftime);
  3574. /*
  3575. * 1. VC 6.0 doesn't support conversion uint64 -> double, so, using int64
  3576. * This should not cause a problems in this (21th) century
  3577. * 2. Windows FILETIME is a number of 100-nanosecond intervals since January
  3578. * 1, 1601 while time_t is a number of _seconds_ since January 1, 1970 UTC,
  3579. * thus, we need to convert to seconds and adjust amount (subtract 11644473600
  3580. * seconds)
  3581. */
  3582. return (double) (((int64_t) ftime.dwLowDateTime +
  3583. ((int64_t) ftime.dwHighDateTime << 32)) /
  3584. 10000000.0) -
  3585. 11644473600;
  3586. #else
  3587. struct timeval tv;
  3588. if (gettimeofday(&tv, NULL /* tz */) != 0) return 0;
  3589. return (double) tv.tv_sec + (((double) tv.tv_usec) / 1000000.0);
  3590. #endif /* _WIN32 */
  3591. }
  3592. void mg_usleep(unsigned long usecs) {
  3593. #if MG_ARCH == MG_ARCH_WIN32
  3594. Sleep(usecs / 1000);
  3595. #elif MG_ARCH == MG_ARCH_ESP8266
  3596. ets_delay_us(usecs);
  3597. #else
  3598. usleep(usecs);
  3599. #endif
  3600. }
  3601. unsigned long mg_millis(void) {
  3602. #if MG_ARCH == MG_ARCH_WIN32
  3603. return GetTickCount();
  3604. #elif MG_ARCH == MG_ARCH_ESP32
  3605. return esp_timer_get_time() / 1000;
  3606. #elif MG_ARCH == MG_ARCH_ESP8266
  3607. // return system_get_time() / 1000;
  3608. return xTaskGetTickCount() * portTICK_PERIOD_MS;
  3609. #elif MG_ARCH == MG_ARCH_FREERTOS
  3610. return xTaskGetTickCount() * portTICK_PERIOD_MS;
  3611. #else
  3612. struct timespec ts;
  3613. clock_gettime(CLOCK_REALTIME, &ts);
  3614. return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
  3615. #endif
  3616. }
  3617. #ifdef MG_ENABLE_LINES
  3618. #line 1 "src/ws.c"
  3619. #endif
  3620. struct ws_msg {
  3621. uint8_t flags;
  3622. size_t header_len;
  3623. size_t data_len;
  3624. };
  3625. static void ws_handshake(struct mg_connection *c, const char *key,
  3626. size_t key_len, const char *fmt, va_list ap) {
  3627. const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
  3628. unsigned char sha[20], b64_sha[30];
  3629. char mem[128], *buf = mem;
  3630. mg_sha1_ctx sha_ctx;
  3631. mg_sha1_init(&sha_ctx);
  3632. mg_sha1_update(&sha_ctx, (unsigned char *) key, key_len);
  3633. mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
  3634. mg_sha1_final(sha, &sha_ctx);
  3635. mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
  3636. buf[0] = '\0';
  3637. if (fmt != NULL) mg_vasprintf(&buf, sizeof(mem), fmt, ap);
  3638. mg_printf(c,
  3639. "HTTP/1.1 101 Switching Protocols\r\n"
  3640. "Upgrade: websocket\r\n"
  3641. "Connection: Upgrade\r\n"
  3642. "Sec-WebSocket-Accept: %s\r\n"
  3643. "%s\r\n",
  3644. b64_sha, buf);
  3645. if (buf != mem) free(buf);
  3646. }
  3647. static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
  3648. size_t i, n = 0, mask_len = 0;
  3649. memset(msg, 0, sizeof(*msg));
  3650. if (len >= 2) {
  3651. n = buf[1] & 0x7f;
  3652. mask_len = buf[1] & WEBSOCKET_FLAGS_MASK_FIN ? 4 : 0;
  3653. msg->flags = *(unsigned char *) buf;
  3654. if (n < 126 && len >= mask_len) {
  3655. msg->data_len = n;
  3656. msg->header_len = 2 + mask_len;
  3657. } else if (n == 126 && len >= 4 + mask_len) {
  3658. msg->header_len = 4 + mask_len;
  3659. msg->data_len = mg_ntohs(*(uint16_t *) &buf[2]);
  3660. } else if (len >= 10 + mask_len) {
  3661. msg->header_len = 10 + mask_len;
  3662. msg->data_len =
  3663. (int) (((uint64_t) mg_ntohl(*(uint32_t *) &buf[2])) << 32) +
  3664. mg_ntohl(*(uint32_t *) &buf[6]);
  3665. }
  3666. }
  3667. if (msg->header_len + msg->data_len > len) return 0;
  3668. if (mask_len > 0) {
  3669. uint8_t *p = buf + msg->header_len, *m = p - mask_len;
  3670. for (i = 0; i < msg->data_len; i++) p[i] ^= m[i & 3];
  3671. }
  3672. return msg->header_len + msg->data_len;
  3673. }
  3674. size_t mg_ws_send(struct mg_connection *c, const char *buf, size_t len,
  3675. int op) {
  3676. unsigned char header[10], mask[4];
  3677. size_t i, header_len = 0;
  3678. header[0] = (uint8_t)(op | WEBSOCKET_FLAGS_MASK_FIN);
  3679. if (len < 126) {
  3680. header[1] = (unsigned char) len;
  3681. header_len = 2;
  3682. } else if (len < 65536) {
  3683. uint16_t tmp = mg_htons((uint16_t) len);
  3684. header[1] = 126;
  3685. memcpy(&header[2], &tmp, sizeof(tmp));
  3686. header_len = 4;
  3687. } else {
  3688. uint32_t tmp;
  3689. header[1] = 127;
  3690. tmp = mg_htonl((uint32_t)((uint64_t) len >> 32));
  3691. memcpy(&header[2], &tmp, sizeof(tmp));
  3692. tmp = mg_htonl((uint32_t)(len & 0xffffffff));
  3693. memcpy(&header[6], &tmp, sizeof(tmp));
  3694. header_len = 10;
  3695. }
  3696. if (c->is_client) header[1] |= 1 << 7; // Set masking flag
  3697. mg_send(c, header, header_len);
  3698. if (c->is_client) {
  3699. mg_random(mask, sizeof(mask));
  3700. mg_send(c, mask, sizeof(mask));
  3701. header_len += sizeof(mask);
  3702. }
  3703. LOG(LL_VERBOSE_DEBUG, ("WS out: %d [%.*s]", (int) len, (int) len, buf));
  3704. mg_send(c, buf, len);
  3705. if (c->is_client && c->send.buf != NULL) {
  3706. uint8_t *p = c->send.buf + c->send.len - len;
  3707. for (i = 0; i < len; i++) p[i] ^= mask[i & 3];
  3708. }
  3709. return header_len + len;
  3710. }
  3711. static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
  3712. void *fn_data) {
  3713. struct ws_msg msg;
  3714. if (ev == MG_EV_READ) {
  3715. if (!c->is_websocket && c->is_client) {
  3716. int n = mg_http_get_request_len(c->recv.buf, c->recv.len);
  3717. if (n < 0) {
  3718. c->is_closing = 1; // Some just, not an HTTP request
  3719. } else if (n > 0) {
  3720. if (n < 15 || memcmp(c->recv.buf + 9, "101", 3) != 0) {
  3721. LOG(LL_ERROR,
  3722. ("%lu WS handshake error: %.*s", c->id, 15, c->recv.buf));
  3723. c->is_closing = 1;
  3724. } else {
  3725. struct mg_http_message hm;
  3726. mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
  3727. c->is_websocket = 1;
  3728. mg_call(c, MG_EV_WS_OPEN, &hm);
  3729. }
  3730. mg_iobuf_delete(&c->recv, n);
  3731. } else {
  3732. return; // A request is not yet received
  3733. }
  3734. }
  3735. while (ws_process(c->recv.buf, c->recv.len, &msg) > 0) {
  3736. char *s = (char *) c->recv.buf + msg.header_len;
  3737. struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
  3738. switch (msg.flags & WEBSOCKET_FLAGS_MASK_OP) {
  3739. case WEBSOCKET_OP_PING:
  3740. LOG(LL_DEBUG, ("%s", "WS PONG"));
  3741. mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG);
  3742. mg_call(c, MG_EV_WS_CTL, &m);
  3743. break;
  3744. case WEBSOCKET_OP_PONG:
  3745. mg_call(c, MG_EV_WS_CTL, &m);
  3746. break;
  3747. case WEBSOCKET_OP_CLOSE:
  3748. LOG(LL_ERROR, ("%lu Got WS CLOSE", c->id));
  3749. mg_call(c, MG_EV_WS_CTL, &m);
  3750. c->is_closing = 1;
  3751. return;
  3752. default: {
  3753. mg_call(c, MG_EV_WS_MSG, &m);
  3754. break;
  3755. }
  3756. }
  3757. mg_iobuf_delete(&c->recv, msg.header_len + msg.data_len);
  3758. }
  3759. }
  3760. (void) fn_data;
  3761. (void) ev_data;
  3762. }
  3763. struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
  3764. mg_event_handler_t fn, void *fn_data,
  3765. const char *fmt, ...) {
  3766. struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
  3767. if (c != NULL) {
  3768. char nonce[16], key[30], mem1[128], mem2[256], *buf1 = mem1, *buf2 = mem2;
  3769. struct mg_str host = mg_url_host(url);
  3770. int n1 = 0, n2 = 0;
  3771. if (fmt != NULL) {
  3772. va_list ap;
  3773. va_start(ap, fmt);
  3774. n1 = mg_vasprintf(&buf1, sizeof(mem1), fmt, ap);
  3775. va_end(ap);
  3776. }
  3777. // Send handshake request
  3778. // mg_url_host(url, host, sizeof(host));
  3779. mg_random(nonce, sizeof(nonce));
  3780. mg_base64_encode((unsigned char *) nonce, sizeof(nonce), key);
  3781. // LOG(LL_DEBUG, "%p [%s]", uri, uri == NULL ? "???" : uri);
  3782. n2 = mg_asprintf(&buf2, sizeof(mem2),
  3783. "GET %s HTTP/1.1\r\n"
  3784. "Upgrade: websocket\r\n"
  3785. "Host: %.*s\r\n"
  3786. "Connection: Upgrade\r\n"
  3787. "%.*s"
  3788. "Sec-WebSocket-Version: 13\r\n"
  3789. "Sec-WebSocket-Key: %s\r\n"
  3790. "\r\n",
  3791. mg_url_uri(url), (int) host.len, host.ptr, n1, buf1, key);
  3792. mg_send(c, buf2, n2);
  3793. if (buf1 != mem1) free(buf1);
  3794. if (buf2 != mem2) free(buf2);
  3795. c->pfn = mg_ws_cb;
  3796. c->fn_data = fn_data;
  3797. }
  3798. return c;
  3799. }
  3800. void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm,
  3801. const char *fmt, ...) {
  3802. struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
  3803. c->pfn = mg_ws_cb;
  3804. if (wskey != NULL) {
  3805. va_list ap;
  3806. va_start(ap, fmt);
  3807. ws_handshake(c, wskey->ptr, wskey->len, fmt, ap);
  3808. va_end(ap);
  3809. }
  3810. c->is_websocket = 1;
  3811. }