adopt.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. */
  24. #include "private-lib-core.h"
  25. static int
  26. lws_get_idlest_tsi(struct lws_context *context)
  27. {
  28. unsigned int lowest = ~0;
  29. int n = 0, hit = -1;
  30. for (; n < context->count_threads; n++) {
  31. lwsl_debug("%s: %d %d\n", __func__, context->pt[n].fds_count,
  32. context->fd_limit_per_thread - 1);
  33. if ((unsigned int)context->pt[n].fds_count !=
  34. context->fd_limit_per_thread - 1 &&
  35. (unsigned int)context->pt[n].fds_count < lowest) {
  36. lowest = context->pt[n].fds_count;
  37. hit = n;
  38. }
  39. }
  40. return hit;
  41. }
  42. struct lws *
  43. lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi)
  44. {
  45. struct lws *new_wsi;
  46. int n = fixed_tsi;
  47. size_t s = sizeof(struct lws);
  48. if (n < 0)
  49. n = lws_get_idlest_tsi(vhost->context);
  50. if (n < 0) {
  51. lwsl_err("no space for new conn\n");
  52. return NULL;
  53. }
  54. #if defined(LWS_WITH_EVENT_LIBS)
  55. s += vhost->context->event_loop_ops->evlib_size_wsi;
  56. #endif
  57. new_wsi = lws_zalloc(s, "new server wsi");
  58. if (new_wsi == NULL) {
  59. lwsl_err("Out of memory for new connection\n");
  60. return NULL;
  61. }
  62. #if defined(LWS_WITH_EVENT_LIBS)
  63. new_wsi->evlib_wsi = (uint8_t *)new_wsi + sizeof(*new_wsi);
  64. #endif
  65. new_wsi->wsistate |= LWSIFR_SERVER;
  66. new_wsi->tsi = n;
  67. lwsl_debug("new wsi %p joining vhost %s, tsi %d\n", new_wsi,
  68. vhost->name, new_wsi->tsi);
  69. lws_vhost_bind_wsi(vhost, new_wsi);
  70. new_wsi->a.context = vhost->context;
  71. new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
  72. new_wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
  73. new_wsi->retry_policy = vhost->retry_policy;
  74. #if defined(LWS_WITH_DETAILED_LATENCY)
  75. if (vhost->context->detailed_latency_cb)
  76. new_wsi->detlat.earliest_write_req_pre_write = lws_now_usecs();
  77. #endif
  78. /* initialize the instance struct */
  79. lwsi_set_state(new_wsi, LRS_UNCONNECTED);
  80. new_wsi->hdr_parsing_completed = 0;
  81. #ifdef LWS_WITH_TLS
  82. new_wsi->tls.use_ssl = LWS_SSL_ENABLED(vhost);
  83. #endif
  84. /*
  85. * these can only be set once the protocol is known
  86. * we set an un-established connection's protocol pointer
  87. * to the start of the supported list, so it can look
  88. * for matching ones during the handshake
  89. */
  90. new_wsi->a.protocol = vhost->protocols;
  91. new_wsi->user_space = NULL;
  92. new_wsi->desc.sockfd = LWS_SOCK_INVALID;
  93. new_wsi->position_in_fds_table = LWS_NO_FDS_POS;
  94. vhost->context->count_wsi_allocated++;
  95. /*
  96. * outermost create notification for wsi
  97. * no user_space because no protocol selection
  98. */
  99. vhost->protocols[0].callback(new_wsi, LWS_CALLBACK_WSI_CREATE, NULL,
  100. NULL, 0);
  101. return new_wsi;
  102. }
  103. /* if not a socket, it's a raw, non-ssl file descriptor */
  104. static struct lws *
  105. lws_adopt_descriptor_vhost1(struct lws_vhost *vh, lws_adoption_type type,
  106. const char *vh_prot_name, struct lws *parent,
  107. void *opaque)
  108. {
  109. struct lws_context *context = vh->context;
  110. struct lws_context_per_thread *pt;
  111. struct lws *new_wsi;
  112. int n;
  113. /*
  114. * Notice that in SMP case, the wsi may be being created on an
  115. * entirely different pt / tsi for load balancing. In that case as
  116. * we initialize it, it may become "live" concurrently unexpectedly...
  117. */
  118. lws_context_lock(vh->context, __func__);
  119. n = -1;
  120. if (parent)
  121. n = parent->tsi;
  122. new_wsi = lws_create_new_server_wsi(vh, n);
  123. if (!new_wsi) {
  124. lws_context_unlock(vh->context);
  125. return NULL;
  126. }
  127. new_wsi->a.opaque_user_data = opaque;
  128. pt = &context->pt[(int)new_wsi->tsi];
  129. lws_pt_lock(pt, __func__);
  130. lws_stats_bump(pt, LWSSTATS_C_CONNECTIONS, 1);
  131. if (parent) {
  132. new_wsi->parent = parent;
  133. new_wsi->sibling_list = parent->child_list;
  134. parent->child_list = new_wsi;
  135. }
  136. if (vh_prot_name) {
  137. new_wsi->a.protocol = lws_vhost_name_to_protocol(new_wsi->a.vhost,
  138. vh_prot_name);
  139. if (!new_wsi->a.protocol) {
  140. lwsl_err("Protocol %s not enabled on vhost %s\n",
  141. vh_prot_name, new_wsi->a.vhost->name);
  142. goto bail;
  143. }
  144. if (lws_ensure_user_space(new_wsi)) {
  145. lwsl_notice("OOM trying to get user_space\n");
  146. goto bail;
  147. }
  148. }
  149. if (!LWS_SSL_ENABLED(new_wsi->a.vhost) ||
  150. !(type & LWS_ADOPT_SOCKET))
  151. type &= ~LWS_ADOPT_ALLOW_SSL;
  152. if (lws_role_call_adoption_bind(new_wsi, type, vh_prot_name)) {
  153. lwsl_err("%s: no role for desc type 0x%x\n", __func__, type);
  154. goto bail;
  155. }
  156. lws_pt_unlock(pt);
  157. /*
  158. * he's an allocated wsi, but he's not on any fds list or child list,
  159. * join him to the vhost's list of these kinds of incomplete wsi until
  160. * he gets another identity (he may do async dns now...)
  161. */
  162. lws_vhost_lock(new_wsi->a.vhost);
  163. lws_dll2_add_head(&new_wsi->vh_awaiting_socket,
  164. &new_wsi->a.vhost->vh_awaiting_socket_owner);
  165. lws_vhost_unlock(new_wsi->a.vhost);
  166. lws_context_unlock(vh->context);
  167. return new_wsi;
  168. bail:
  169. lwsl_notice("%s: exiting on bail\n", __func__);
  170. if (parent)
  171. parent->child_list = new_wsi->sibling_list;
  172. if (new_wsi->user_space)
  173. lws_free(new_wsi->user_space);
  174. vh->context->count_wsi_allocated--;
  175. lws_vhost_unbind_wsi(new_wsi);
  176. lws_free(new_wsi);
  177. lws_pt_unlock(pt);
  178. lws_context_unlock(vh->context);
  179. return NULL;
  180. }
  181. #if defined(LWS_WITH_SERVER) && defined(LWS_WITH_SECURE_STREAMS)
  182. /*
  183. * If the incoming wsi is bound to a vhost that is a ss server, this creates
  184. * an accepted ss bound to the wsi.
  185. *
  186. * For h1 or raw, we can do the binding here, but for muxed protocols like h2
  187. * or mqtt we have to do it not on the nwsi but on the stream. And for h2 we
  188. * start off bound to h1 role, since we don't know if we will upgrade to h2
  189. * until we meet the server.
  190. *
  191. * 1) No tls is assumed to mean no muxed protocol so can do it at adopt.
  192. *
  193. * 2) After alpn if not muxed we can do it.
  194. *
  195. * 3) For muxed, do it at the nwsi migration and on new stream
  196. */
  197. int
  198. lws_adopt_ss_server_accept(struct lws *new_wsi)
  199. {
  200. lws_ss_handle_t *h;
  201. void *pv, **ppv;
  202. if (!new_wsi->a.vhost->ss_handle)
  203. return 0;
  204. pv = (char *)&new_wsi->a.vhost->ss_handle[1];
  205. /*
  206. * Yes... the vhost is pointing to its secure stream representing the
  207. * server... we want to create an accepted SS and bind it to new_wsi,
  208. * the info/ssi from the server SS (so the SS callbacks defined there),
  209. * the opaque_user_data of the server object and the policy of it.
  210. */
  211. ppv = (void **)((char *)pv +
  212. new_wsi->a.vhost->ss_handle->info.opaque_user_data_offset);
  213. /*
  214. * indicate we are an accepted connection referencing the
  215. * server object
  216. */
  217. new_wsi->a.vhost->ss_handle->info.flags |= LWSSSINFLAGS_SERVER;
  218. if (lws_ss_create(new_wsi->a.context, new_wsi->tsi,
  219. &new_wsi->a.vhost->ss_handle->info,
  220. *ppv, &h, NULL, NULL)) {
  221. lwsl_err("%s: accept ss creation failed\n", __func__);
  222. goto fail1;
  223. }
  224. /*
  225. * We made a fresh accepted SS conn from the server pieces,
  226. * now bind the wsi... the problem is, this is the nwsi if it's
  227. * h2.
  228. */
  229. h->wsi = new_wsi;
  230. new_wsi->a.opaque_user_data = h;
  231. h->info.flags |= LWSSSINFLAGS_ACCEPTED;
  232. new_wsi->for_ss = 1; /* indicate wsi should invalidate any ss link to it on close */
  233. // lwsl_notice("%s: opaq %p, role %s\n", __func__,
  234. // new_wsi->a.opaque_user_data, new_wsi->role_ops->name);
  235. h->policy = new_wsi->a.vhost->ss_handle->policy;
  236. /*
  237. * Let's give it appropriate state notifications
  238. */
  239. if (lws_ss_event_helper(h, LWSSSCS_CREATING))
  240. goto fail;
  241. if (lws_ss_event_helper(h, LWSSSCS_CONNECTING))
  242. goto fail;
  243. if (lws_ss_event_helper(h, LWSSSCS_CONNECTED))
  244. goto fail;
  245. // lwsl_notice("%s: accepted ss complete, pcol %s\n", __func__,
  246. // new_wsi->a.protocol->name);
  247. return 0;
  248. fail:
  249. lws_ss_destroy(&h);
  250. fail1:
  251. return 1;
  252. }
  253. #endif
  254. static struct lws *
  255. lws_adopt_descriptor_vhost2(struct lws *new_wsi, lws_adoption_type type,
  256. lws_sock_file_fd_type fd)
  257. {
  258. struct lws_context_per_thread *pt =
  259. &new_wsi->a.context->pt[(int)new_wsi->tsi];
  260. int n;
  261. /* enforce that every fd is nonblocking */
  262. if (type & LWS_ADOPT_SOCKET) {
  263. if (lws_plat_set_nonblocking(fd.sockfd)) {
  264. lwsl_err("%s: unable to set sockfd %d nonblocking\n",
  265. __func__, fd.sockfd);
  266. goto fail;
  267. }
  268. }
  269. #if !defined(WIN32)
  270. else
  271. if (lws_plat_set_nonblocking(fd.filefd)) {
  272. lwsl_err("%s: unable to set filefd nonblocking\n",
  273. __func__);
  274. goto fail;
  275. }
  276. #endif
  277. new_wsi->desc = fd;
  278. if (!LWS_SSL_ENABLED(new_wsi->a.vhost) ||
  279. !(type & LWS_ADOPT_SOCKET))
  280. type &= ~LWS_ADOPT_ALLOW_SSL;
  281. /*
  282. * A new connection was accepted. Give the user a chance to
  283. * set properties of the newly created wsi. There's no protocol
  284. * selected yet so we issue this to the vhosts's default protocol,
  285. * itself by default protocols[0]
  286. */
  287. new_wsi->wsistate |= LWSIFR_SERVER;
  288. n = LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED;
  289. if (new_wsi->role_ops->adoption_cb[lwsi_role_server(new_wsi)])
  290. n = new_wsi->role_ops->adoption_cb[lwsi_role_server(new_wsi)];
  291. if (new_wsi->a.context->event_loop_ops->sock_accept)
  292. if (new_wsi->a.context->event_loop_ops->sock_accept(new_wsi))
  293. goto fail;
  294. #if LWS_MAX_SMP > 1
  295. /*
  296. * Caution: after this point the wsi is live on its service thread
  297. * which may be concurrent to this. We mark the wsi as still undergoing
  298. * init in another pt so the assigned pt leaves it alone.
  299. */
  300. new_wsi->undergoing_init_from_other_pt = 1;
  301. #endif
  302. if (!(type & LWS_ADOPT_ALLOW_SSL)) {
  303. lws_pt_lock(pt, __func__);
  304. if (__insert_wsi_socket_into_fds(new_wsi->a.context, new_wsi)) {
  305. lws_pt_unlock(pt);
  306. lwsl_err("%s: fail inserting socket\n", __func__);
  307. goto fail;
  308. }
  309. lws_pt_unlock(pt);
  310. }
  311. #if defined(LWS_WITH_SERVER)
  312. else
  313. if (lws_server_socket_service_ssl(new_wsi, fd.sockfd, 0)) {
  314. #if defined(LWS_WITH_ACCESS_LOG)
  315. lwsl_notice("%s: fail ssl negotiation: %s\n", __func__,
  316. new_wsi->simple_ip);
  317. #else
  318. lwsl_info("%s: fail ssl negotiation\n", __func__);
  319. #endif
  320. goto fail;
  321. }
  322. #endif
  323. lws_vhost_lock(new_wsi->a.vhost);
  324. /* he has fds visibility now, remove from vhost orphan list */
  325. lws_dll2_remove(&new_wsi->vh_awaiting_socket);
  326. lws_vhost_unlock(new_wsi->a.vhost);
  327. /*
  328. * by deferring callback to this point, after insertion to fds,
  329. * lws_callback_on_writable() can work from the callback
  330. */
  331. if ((new_wsi->a.protocol->callback)(new_wsi, n, new_wsi->user_space,
  332. NULL, 0))
  333. goto fail;
  334. /* role may need to do something after all adoption completed */
  335. lws_role_call_adoption_bind(new_wsi, type | _LWS_ADOPT_FINISH,
  336. new_wsi->a.protocol->name);
  337. #if defined(LWS_WITH_SERVER) && defined(LWS_WITH_SECURE_STREAMS)
  338. /*
  339. * Did we come from an accepted client connection to a ss server?
  340. *
  341. * !!! For mux protocols, this will cause an additional inactive ss
  342. * representing the nwsi. Doing that allows us to support both h1
  343. * (here) and h2 (at lws_wsi_server_new())
  344. */
  345. lwsl_info("%s: wsi %p, vhost %s ss_handle %p\n", __func__, new_wsi,
  346. new_wsi->a.vhost->name, new_wsi->a.vhost->ss_handle);
  347. if (lws_adopt_ss_server_accept(new_wsi))
  348. goto fail;
  349. #endif
  350. #if LWS_MAX_SMP > 1
  351. /* its actual pt can service it now */
  352. new_wsi->undergoing_init_from_other_pt = 0;
  353. #endif
  354. lws_cancel_service_pt(new_wsi);
  355. return new_wsi;
  356. fail:
  357. if (type & LWS_ADOPT_SOCKET)
  358. lws_close_free_wsi(new_wsi, LWS_CLOSE_STATUS_NOSTATUS,
  359. "adopt skt fail");
  360. return NULL;
  361. }
  362. /* if not a socket, it's a raw, non-ssl file descriptor */
  363. struct lws *
  364. lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
  365. lws_sock_file_fd_type fd, const char *vh_prot_name,
  366. struct lws *parent)
  367. {
  368. lws_adopt_desc_t info;
  369. memset(&info, 0, sizeof(info));
  370. info.vh = vh;
  371. info.type = type;
  372. info.fd = fd;
  373. info.vh_prot_name = vh_prot_name;
  374. info.parent = parent;
  375. return lws_adopt_descriptor_vhost_via_info(&info);
  376. }
  377. struct lws *
  378. lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t *info)
  379. {
  380. struct lws *new_wsi;
  381. #if defined(LWS_WITH_PEER_LIMITS)
  382. struct lws_peer *peer = NULL;
  383. if (info->type & LWS_ADOPT_SOCKET) {
  384. peer = lws_get_or_create_peer(info->vh, info->fd.sockfd);
  385. if (peer && info->vh->context->ip_limit_wsi &&
  386. peer->count_wsi >= info->vh->context->ip_limit_wsi) {
  387. lwsl_info("Peer reached wsi limit %d\n",
  388. info->vh->context->ip_limit_wsi);
  389. lws_stats_bump(&info->vh->context->pt[0],
  390. LWSSTATS_C_PEER_LIMIT_WSI_DENIED,
  391. 1);
  392. if (info->vh->context->pl_notify_cb)
  393. info->vh->context->pl_notify_cb(
  394. info->vh->context,
  395. info->fd.sockfd,
  396. &peer->sa46);
  397. compatible_close(info->fd.sockfd);
  398. return NULL;
  399. }
  400. }
  401. #endif
  402. new_wsi = lws_adopt_descriptor_vhost1(info->vh, info->type,
  403. info->vh_prot_name, info->parent,
  404. info->opaque);
  405. if (!new_wsi) {
  406. if (info->type & LWS_ADOPT_SOCKET)
  407. compatible_close(info->fd.sockfd);
  408. return NULL;
  409. }
  410. #if defined(LWS_WITH_ACCESS_LOG)
  411. lws_get_peer_simple_fd(info->fd.sockfd, new_wsi->simple_ip,
  412. sizeof(new_wsi->simple_ip));
  413. #endif
  414. #if defined(LWS_WITH_PEER_LIMITS)
  415. if (peer)
  416. lws_peer_add_wsi(info->vh->context, peer, new_wsi);
  417. #endif
  418. return lws_adopt_descriptor_vhost2(new_wsi, info->type, info->fd);
  419. }
  420. struct lws *
  421. lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd)
  422. {
  423. lws_sock_file_fd_type fd;
  424. fd.sockfd = accept_fd;
  425. return lws_adopt_descriptor_vhost(vh, LWS_ADOPT_SOCKET |
  426. LWS_ADOPT_HTTP | LWS_ADOPT_ALLOW_SSL, fd, NULL, NULL);
  427. }
  428. struct lws *
  429. lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd)
  430. {
  431. return lws_adopt_socket_vhost(context->vhost_list, accept_fd);
  432. }
  433. /* Common read-buffer adoption for lws_adopt_*_readbuf */
  434. static struct lws*
  435. adopt_socket_readbuf(struct lws *wsi, const char *readbuf, size_t len)
  436. {
  437. struct lws_context_per_thread *pt;
  438. struct lws_pollfd *pfd;
  439. int n;
  440. if (!wsi)
  441. return NULL;
  442. if (!readbuf || len == 0)
  443. return wsi;
  444. if (wsi->position_in_fds_table == LWS_NO_FDS_POS)
  445. return wsi;
  446. pt = &wsi->a.context->pt[(int)wsi->tsi];
  447. n = lws_buflist_append_segment(&wsi->buflist, (const uint8_t *)readbuf,
  448. len);
  449. if (n < 0)
  450. goto bail;
  451. if (n)
  452. lws_dll2_add_head(&wsi->dll_buflist, &pt->dll_buflist_owner);
  453. /*
  454. * we can't process the initial read data until we can attach an ah.
  455. *
  456. * if one is available, get it and place the data in his ah rxbuf...
  457. * wsi with ah that have pending rxbuf get auto-POLLIN service.
  458. *
  459. * no autoservice because we didn't get a chance to attach the
  460. * readbuf data to wsi or ah yet, and we will do it next if we get
  461. * the ah.
  462. */
  463. if (wsi->http.ah || !lws_header_table_attach(wsi, 0)) {
  464. lwsl_notice("%s: calling service on readbuf ah\n", __func__);
  465. /*
  466. * unlike a normal connect, we have the headers already
  467. * (or the first part of them anyway).
  468. * libuv won't come back and service us without a network
  469. * event, so we need to do the header service right here.
  470. */
  471. pfd = &pt->fds[wsi->position_in_fds_table];
  472. pfd->revents |= LWS_POLLIN;
  473. lwsl_err("%s: calling service\n", __func__);
  474. if (lws_service_fd_tsi(wsi->a.context, pfd, wsi->tsi))
  475. /* service closed us */
  476. return NULL;
  477. return wsi;
  478. }
  479. lwsl_err("%s: deferring handling ah\n", __func__);
  480. return wsi;
  481. bail:
  482. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,
  483. "adopt skt readbuf fail");
  484. return NULL;
  485. }
  486. #if defined(LWS_WITH_UDP)
  487. #if defined(LWS_WITH_CLIENT)
  488. static struct lws *
  489. lws_create_adopt_udp2(struct lws *wsi, const char *ads,
  490. const struct addrinfo *r, int n, void *opaque)
  491. {
  492. lws_sock_file_fd_type sock;
  493. int bc = 1;
  494. assert(wsi);
  495. if (!wsi->dns_results)
  496. wsi->dns_results_next = wsi->dns_results = r;
  497. if (ads && (n < 0 || !r)) {
  498. /*
  499. * DNS lookup failed: there are no usable results. Fail the
  500. * overall connection request.
  501. */
  502. lwsl_notice("%s: bad: n %d, r %p\n", __func__, n, r);
  503. /*
  504. * We didn't get a callback on a cache item and bump the
  505. * refcount. So don't let the cleanup continue to think it
  506. * needs to decrement any refcount.
  507. */
  508. wsi->dns_results_next = wsi->dns_results = NULL;
  509. goto bail;
  510. }
  511. while (wsi->dns_results_next) {
  512. /*
  513. * We have done the dns lookup, identify the result we want
  514. * if any, and then complete the adoption by binding wsi to
  515. * socket opened on it.
  516. *
  517. * Ignore the weak assumptions about protocol driven by port
  518. * number and force to DGRAM / UDP since that's what this
  519. * function is for.
  520. */
  521. #if !defined(__linux__)
  522. /* PF_PACKET is linux-only */
  523. sock.sockfd = socket(wsi->dns_results_next->ai_family,
  524. SOCK_DGRAM, IPPROTO_UDP);
  525. #else
  526. sock.sockfd = socket(wsi->pf_packet ? PF_PACKET :
  527. wsi->dns_results_next->ai_family,
  528. SOCK_DGRAM, wsi->pf_packet ?
  529. htons(0x800) : IPPROTO_UDP);
  530. #endif
  531. if (sock.sockfd == LWS_SOCK_INVALID)
  532. goto resume;
  533. ((struct sockaddr_in *)wsi->dns_results_next->ai_addr)->sin_port =
  534. htons(wsi->c_port);
  535. if (setsockopt(sock.sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&bc,
  536. sizeof(bc)) < 0)
  537. lwsl_err("%s: failed to set reuse\n", __func__);
  538. if (wsi->do_broadcast &&
  539. setsockopt(sock.sockfd, SOL_SOCKET, SO_BROADCAST, (const char *)&bc,
  540. sizeof(bc)) < 0)
  541. lwsl_err("%s: failed to set broadcast\n",
  542. __func__);
  543. /* Bind the udp socket to a particular network interface */
  544. if (opaque &&
  545. lws_plat_BINDTODEVICE(sock.sockfd, (const char *)opaque))
  546. goto resume;
  547. if (wsi->do_bind &&
  548. bind(sock.sockfd, wsi->dns_results_next->ai_addr,
  549. #if defined(_WIN32)
  550. (int)wsi->dns_results_next->ai_addrlen
  551. #else
  552. sizeof(struct sockaddr)//wsi->dns_results_next->ai_addrlen
  553. #endif
  554. ) == -1) {
  555. lwsl_err("%s: bind failed\n", __func__);
  556. goto resume;
  557. }
  558. if (!wsi->do_bind && !wsi->pf_packet) {
  559. #if !defined(__APPLE__)
  560. if (connect(sock.sockfd, wsi->dns_results_next->ai_addr,
  561. (socklen_t)wsi->dns_results_next->ai_addrlen) == -1) {
  562. lwsl_err("%s: conn fd %d fam %d %s:%u failed "
  563. "(salen %d) errno %d\n", __func__,
  564. sock.sockfd,
  565. wsi->dns_results_next->ai_addr->sa_family,
  566. ads ? ads : "null", wsi->c_port,
  567. (int)wsi->dns_results_next->ai_addrlen,
  568. LWS_ERRNO);
  569. compatible_close(sock.sockfd);
  570. goto resume;
  571. }
  572. #endif
  573. memcpy(&wsi->udp->sa, wsi->dns_results_next->ai_addr,
  574. wsi->dns_results_next->ai_addrlen);
  575. wsi->udp->salen = (socklen_t)wsi->dns_results_next->ai_addrlen;
  576. }
  577. /* we connected: complete the udp socket adoption flow */
  578. lws_addrinfo_clean(wsi);
  579. return lws_adopt_descriptor_vhost2(wsi,
  580. LWS_ADOPT_RAW_SOCKET_UDP, sock);
  581. resume:
  582. wsi->dns_results_next = wsi->dns_results_next->ai_next;
  583. }
  584. lwsl_err("%s: unable to create INET socket %d\n", __func__, LWS_ERRNO);
  585. lws_addrinfo_clean(wsi);
  586. bail:
  587. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "adopt udp2 fail");
  588. return NULL;
  589. }
  590. struct lws *
  591. lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
  592. int flags, const char *protocol_name, const char *ifname,
  593. struct lws *parent_wsi, void *opaque,
  594. const lws_retry_bo_t *retry_policy)
  595. {
  596. #if !defined(LWS_PLAT_OPTEE)
  597. struct lws *wsi;
  598. int n;
  599. lwsl_info("%s: %s:%u\n", __func__, ads ? ads : "null", port);
  600. /* create the logical wsi without any valid fd */
  601. wsi = lws_adopt_descriptor_vhost1(vhost, LWS_ADOPT_RAW_SOCKET_UDP,
  602. protocol_name, parent_wsi, opaque);
  603. if (!wsi) {
  604. lwsl_err("%s: udp wsi creation failed\n", __func__);
  605. goto bail;
  606. }
  607. wsi->do_bind = !!(flags & LWS_CAUDP_BIND);
  608. wsi->do_broadcast = !!(flags & LWS_CAUDP_BROADCAST);
  609. wsi->pf_packet = !!(flags & LWS_CAUDP_PF_PACKET);
  610. wsi->c_port = port;
  611. if (retry_policy)
  612. wsi->retry_policy = retry_policy;
  613. else
  614. wsi->retry_policy = vhost->retry_policy;
  615. #if !defined(LWS_WITH_SYS_ASYNC_DNS)
  616. {
  617. struct addrinfo *r, h;
  618. char buf[16];
  619. memset(&h, 0, sizeof(h));
  620. h.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
  621. h.ai_socktype = SOCK_DGRAM;
  622. h.ai_protocol = IPPROTO_UDP;
  623. #if defined(AI_PASSIVE)
  624. h.ai_flags = AI_PASSIVE;
  625. #endif
  626. #ifdef AI_ADDRCONFIG
  627. h.ai_flags |= AI_ADDRCONFIG;
  628. #endif
  629. /* if the dns lookup is synchronous, do the whole thing now */
  630. lws_snprintf(buf, sizeof(buf), "%u", port);
  631. n = getaddrinfo(ads, buf, &h, &r);
  632. if (n) {
  633. #if !defined(LWS_PLAT_FREERTOS)
  634. lwsl_info("%s: getaddrinfo error: %s\n", __func__,
  635. gai_strerror(n));
  636. #else
  637. lwsl_info("%s: getaddrinfo error: %s\n", __func__,
  638. strerror(n));
  639. #endif
  640. //freeaddrinfo(r);
  641. goto bail1;
  642. }
  643. /* complete it immediately after the blocking dns lookup
  644. * finished... free r when connect either completed or failed */
  645. wsi = lws_create_adopt_udp2(wsi, ads, r, 0, NULL);
  646. return wsi;
  647. }
  648. #else
  649. if (ads) {
  650. /*
  651. * with async dns, use the wsi as the point about which to do
  652. * the dns lookup and have it call the second part when it's
  653. * done.
  654. *
  655. * Keep a refcount on the results and free it when we connected
  656. * or definitively failed.
  657. *
  658. * Notice wsi has no socket at this point (we don't know what
  659. * kind to ask for until we get the dns back). But it is bound
  660. * to a vhost and can be cleaned up from that at vhost destroy.
  661. */
  662. n = lws_async_dns_query(vhost->context, 0, ads,
  663. LWS_ADNS_RECORD_A,
  664. lws_create_adopt_udp2, wsi, (void *)ifname);
  665. lwsl_debug("%s: dns query returned %d\n", __func__, n);
  666. if (n == LADNS_RET_FAILED) {
  667. lwsl_err("%s: async dns failed\n", __func__);
  668. wsi = NULL;
  669. /*
  670. * It was already closed by calling callback with error
  671. * from lws_async_dns_query()
  672. */
  673. goto bail;
  674. }
  675. } else {
  676. lwsl_debug("%s: udp adopt has no ads\n", __func__);
  677. wsi = lws_create_adopt_udp2(wsi, ads, NULL, 0, (void *)ifname);
  678. }
  679. /* dns lookup is happening asynchronously */
  680. lwsl_debug("%s: returning wsi %p\n", __func__, wsi);
  681. return wsi;
  682. #endif
  683. #if !defined(LWS_WITH_SYS_ASYNC_DNS)
  684. bail1:
  685. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "adopt udp2 fail");
  686. wsi = NULL;
  687. #endif
  688. bail:
  689. return wsi;
  690. #else
  691. return NULL;
  692. #endif
  693. }
  694. #endif
  695. #endif
  696. struct lws *
  697. lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
  698. const char *readbuf, size_t len)
  699. {
  700. return adopt_socket_readbuf(lws_adopt_socket(context, accept_fd),
  701. readbuf, len);
  702. }
  703. struct lws *
  704. lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost,
  705. lws_sockfd_type accept_fd,
  706. const char *readbuf, size_t len)
  707. {
  708. return adopt_socket_readbuf(lws_adopt_socket_vhost(vhost, accept_fd),
  709. readbuf, len);
  710. }