client-handshake.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  1. #include "core/private.h"
  2. static int
  3. lws_getaddrinfo46(struct lws *wsi, const char *ads, struct addrinfo **result)
  4. {
  5. struct addrinfo hints;
  6. memset(&hints, 0, sizeof(hints));
  7. *result = NULL;
  8. #ifdef LWS_WITH_IPV6
  9. if (wsi->ipv6) {
  10. #if !defined(__ANDROID__)
  11. hints.ai_family = AF_INET6;
  12. hints.ai_flags = AI_V4MAPPED;
  13. #endif
  14. } else
  15. #endif
  16. {
  17. hints.ai_family = PF_UNSPEC;
  18. hints.ai_socktype = SOCK_STREAM;
  19. }
  20. return getaddrinfo(ads, NULL, &hints, result);
  21. }
  22. struct lws *
  23. lws_client_connect_2(struct lws *wsi)
  24. {
  25. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  26. struct lws_context *context = wsi->context;
  27. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  28. const char *adsin;
  29. struct lws *wsi_piggyback = NULL;
  30. struct lws_pollfd pfd;
  31. ssize_t plen = 0;
  32. #endif
  33. struct addrinfo *result;
  34. #if defined(LWS_WITH_UNIX_SOCK)
  35. struct sockaddr_un sau;
  36. char unix_skt = 0;
  37. #endif
  38. const char *ads;
  39. sockaddr46 sa46;
  40. const struct sockaddr *psa;
  41. int n, port = 0;
  42. const char *cce = "", *iface;
  43. const char *meth = NULL;
  44. #ifdef LWS_WITH_IPV6
  45. char ipv6only = lws_check_opt(wsi->vhost->options,
  46. LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY |
  47. LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE);
  48. #if defined(__ANDROID__)
  49. ipv6only = 0;
  50. #endif
  51. #endif
  52. lwsl_client("%s: %p\n", __func__, wsi);
  53. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  54. if (!wsi->http.ah) {
  55. cce = "ah was NULL at cc2";
  56. lwsl_err("%s\n", cce);
  57. goto oom4;
  58. }
  59. /* we can only piggyback GET or POST */
  60. meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
  61. if (meth && strcmp(meth, "GET") && strcmp(meth, "POST"))
  62. goto create_new_conn;
  63. /* we only pipeline connections that said it was okay */
  64. if (!wsi->client_pipeline)
  65. goto create_new_conn;
  66. /*
  67. * let's take a look first and see if there are any already-active
  68. * client connections we can piggy-back on.
  69. */
  70. adsin = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
  71. lws_vhost_lock(wsi->vhost); /* ----------------------------------- { */
  72. lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,
  73. wsi->vhost->dll_active_client_conns.next) {
  74. struct lws *w = lws_container_of(d, struct lws,
  75. dll_active_client_conns);
  76. lwsl_debug("%s: check %s %s %d %d\n", __func__, adsin,
  77. w->client_hostname_copy, wsi->c_port, w->c_port);
  78. if (w != wsi && w->client_hostname_copy &&
  79. !strcmp(adsin, w->client_hostname_copy) &&
  80. #if defined(LWS_WITH_TLS)
  81. (wsi->tls.use_ssl & LCCSCF_USE_SSL) ==
  82. (w->tls.use_ssl & LCCSCF_USE_SSL) &&
  83. #endif
  84. wsi->c_port == w->c_port) {
  85. /* someone else is already connected to the right guy */
  86. /* do we know for a fact pipelining won't fly? */
  87. if (w->keepalive_rejected) {
  88. lwsl_info("defeating pipelining due to no "
  89. "keepalive on server\n");
  90. lws_vhost_unlock(wsi->vhost); /* } ---------- */
  91. goto create_new_conn;
  92. }
  93. #if defined (LWS_WITH_HTTP2)
  94. /*
  95. * h2: in usable state already: just use it without
  96. * going through the queue
  97. */
  98. if (w->client_h2_alpn &&
  99. (lwsi_state(w) == LRS_H2_WAITING_TO_SEND_HEADERS ||
  100. lwsi_state(w) == LRS_ESTABLISHED)) {
  101. lwsl_info("%s: just join h2 directly\n",
  102. __func__);
  103. wsi->client_h2_alpn = 1;
  104. lws_wsi_h2_adopt(w, wsi);
  105. lws_vhost_unlock(wsi->vhost); /* } ---------- */
  106. return wsi;
  107. }
  108. #endif
  109. lwsl_info("applying %p to txn queue on %p state 0x%x\n",
  110. wsi, w, w->wsistate);
  111. /*
  112. * ...let's add ourselves to his transaction queue...
  113. * we are adding ourselves at the HEAD
  114. */
  115. lws_dll_lws_add_front(&wsi->dll_client_transaction_queue,
  116. &w->dll_client_transaction_queue_head);
  117. /*
  118. * h1: pipeline our headers out on him,
  119. * and wait for our turn at client transaction_complete
  120. * to take over parsing the rx.
  121. */
  122. wsi_piggyback = w;
  123. lws_vhost_unlock(wsi->vhost); /* } ---------- */
  124. goto send_hs;
  125. }
  126. } lws_end_foreach_dll_safe(d, d1);
  127. lws_vhost_unlock(wsi->vhost); /* } ---------------------------------- */
  128. create_new_conn:
  129. #endif
  130. /*
  131. * clients who will create their own fresh connection keep a copy of
  132. * the hostname they originally connected to, in case other connections
  133. * want to use it too
  134. */
  135. if (!wsi->client_hostname_copy)
  136. wsi->client_hostname_copy =
  137. lws_strdup(lws_hdr_simple_ptr(wsi,
  138. _WSI_TOKEN_CLIENT_PEER_ADDRESS));
  139. /*
  140. * If we made our own connection, and we're doing a method that can take
  141. * a pipeline, we are an "active client connection".
  142. *
  143. * Add ourselves to the vhost list of those so that others can
  144. * piggyback on our transaction queue
  145. */
  146. if (meth && (!strcmp(meth, "GET") || !strcmp(meth, "POST")) &&
  147. lws_dll_is_null(&wsi->dll_client_transaction_queue) &&
  148. lws_dll_is_null(&wsi->dll_active_client_conns)) {
  149. lws_vhost_lock(wsi->vhost);
  150. /* caution... we will have to unpick this on oom4 path */
  151. lws_dll_lws_add_front(&wsi->dll_active_client_conns,
  152. &wsi->vhost->dll_active_client_conns);
  153. lws_vhost_unlock(wsi->vhost);
  154. }
  155. /*
  156. * unix socket destination?
  157. */
  158. ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
  159. #if defined(LWS_WITH_UNIX_SOCK)
  160. if (*ads == '+') {
  161. ads++;
  162. memset(&sau, 0, sizeof(sau));
  163. sau.sun_family = AF_UNIX;
  164. strncpy(sau.sun_path, ads, sizeof(sau.sun_path));
  165. sau.sun_path[sizeof(sau.sun_path) - 1] = '\0';
  166. lwsl_info("%s: Unix skt: %s\n", __func__, ads);
  167. if (sau.sun_path[0] == '@')
  168. sau.sun_path[0] = '\0';
  169. unix_skt = 1;
  170. goto ads_known;
  171. }
  172. #endif
  173. /*
  174. * start off allowing ipv6 on connection if vhost allows it
  175. */
  176. wsi->ipv6 = LWS_IPV6_ENABLED(wsi->vhost);
  177. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  178. /* Decide what it is we need to connect to:
  179. *
  180. * Priority 1: connect to http proxy */
  181. if (wsi->vhost->http.http_proxy_port) {
  182. plen = sprintf((char *)pt->serv_buf,
  183. "CONNECT %s:%u HTTP/1.0\x0d\x0a"
  184. "User-agent: libwebsockets\x0d\x0a",
  185. lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
  186. wsi->c_port);
  187. if (wsi->vhost->proxy_basic_auth_token[0])
  188. plen += sprintf((char *)pt->serv_buf + plen,
  189. "Proxy-authorization: basic %s\x0d\x0a",
  190. wsi->vhost->proxy_basic_auth_token);
  191. plen += sprintf((char *)pt->serv_buf + plen, "\x0d\x0a");
  192. ads = wsi->vhost->http.http_proxy_address;
  193. port = wsi->vhost->http.http_proxy_port;
  194. #else
  195. if (0) {
  196. #endif
  197. #if defined(LWS_WITH_SOCKS5)
  198. /* Priority 2: Connect to SOCK5 Proxy */
  199. } else if (wsi->vhost->socks_proxy_port) {
  200. socks_generate_msg(wsi, SOCKS_MSG_GREETING, &plen);
  201. lwsl_client("Sending SOCKS Greeting\n");
  202. ads = wsi->vhost->socks_proxy_address;
  203. port = wsi->vhost->socks_proxy_port;
  204. #endif
  205. } else {
  206. /* Priority 3: Connect directly */
  207. ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
  208. port = wsi->c_port;
  209. }
  210. /*
  211. * prepare the actual connection
  212. * to whatever we decided to connect to
  213. */
  214. lwsl_info("%s: %p: address %s\n", __func__, wsi, ads);
  215. n = lws_getaddrinfo46(wsi, ads, &result);
  216. #ifdef LWS_WITH_IPV6
  217. if (wsi->ipv6) {
  218. struct sockaddr_in6 *sa6;
  219. if (n || !result) {
  220. /* lws_getaddrinfo46 failed, there is no usable result */
  221. lwsl_notice("%s: lws_getaddrinfo46 failed %d\n",
  222. __func__, n);
  223. cce = "ipv6 lws_getaddrinfo46 failed";
  224. goto oom4;
  225. }
  226. sa6 = ((struct sockaddr_in6 *)result->ai_addr);
  227. memset(&sa46, 0, sizeof(sa46));
  228. sa46.sa6.sin6_family = AF_INET6;
  229. switch (result->ai_family) {
  230. case AF_INET:
  231. if (ipv6only)
  232. break;
  233. /* map IPv4 to IPv6 */
  234. bzero((char *)&sa46.sa6.sin6_addr,
  235. sizeof(sa46.sa6.sin6_addr));
  236. sa46.sa6.sin6_addr.s6_addr[10] = 0xff;
  237. sa46.sa6.sin6_addr.s6_addr[11] = 0xff;
  238. memcpy(&sa46.sa6.sin6_addr.s6_addr[12],
  239. &((struct sockaddr_in *)result->ai_addr)->sin_addr,
  240. sizeof(struct in_addr));
  241. lwsl_notice("uplevelling AF_INET to AF_INET6\n");
  242. break;
  243. case AF_INET6:
  244. memcpy(&sa46.sa6.sin6_addr, &sa6->sin6_addr,
  245. sizeof(struct in6_addr));
  246. sa46.sa6.sin6_scope_id = sa6->sin6_scope_id;
  247. sa46.sa6.sin6_flowinfo = sa6->sin6_flowinfo;
  248. break;
  249. default:
  250. lwsl_err("Unknown address family\n");
  251. freeaddrinfo(result);
  252. cce = "unknown address family";
  253. goto oom4;
  254. }
  255. } else
  256. #endif /* use ipv6 */
  257. /* use ipv4 */
  258. {
  259. void *p = NULL;
  260. if (!n) {
  261. struct addrinfo *res = result;
  262. /* pick the first AF_INET (IPv4) result */
  263. while (!p && res) {
  264. switch (res->ai_family) {
  265. case AF_INET:
  266. p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
  267. break;
  268. }
  269. res = res->ai_next;
  270. }
  271. #if defined(LWS_FALLBACK_GETHOSTBYNAME)
  272. } else if (n == EAI_SYSTEM) {
  273. struct hostent *host;
  274. lwsl_info("ipv4 getaddrinfo err, try gethostbyname\n");
  275. host = gethostbyname(ads);
  276. if (host) {
  277. p = host->h_addr;
  278. } else {
  279. lwsl_err("gethostbyname failed\n");
  280. cce = "gethostbyname (ipv4) failed";
  281. goto oom4;
  282. }
  283. #endif
  284. } else {
  285. lwsl_err("getaddrinfo failed: %d\n", n);
  286. cce = "getaddrinfo failed";
  287. goto oom4;
  288. }
  289. if (!p) {
  290. if (result)
  291. freeaddrinfo(result);
  292. lwsl_err("Couldn't identify address\n");
  293. cce = "unable to lookup address";
  294. goto oom4;
  295. }
  296. sa46.sa4.sin_family = AF_INET;
  297. sa46.sa4.sin_addr = *((struct in_addr *)p);
  298. bzero(&sa46.sa4.sin_zero, 8);
  299. }
  300. if (result)
  301. freeaddrinfo(result);
  302. #if defined(LWS_WITH_UNIX_SOCK)
  303. ads_known:
  304. #endif
  305. /* now we decided on ipv4 or ipv6, set the port */
  306. if (!lws_socket_is_valid(wsi->desc.sockfd)) {
  307. if (wsi->context->event_loop_ops->check_client_connect_ok &&
  308. wsi->context->event_loop_ops->check_client_connect_ok(wsi)) {
  309. cce = "waiting for event loop watcher to close";
  310. goto oom4;
  311. }
  312. #if defined(LWS_WITH_UNIX_SOCK)
  313. if (unix_skt) {
  314. wsi->unix_skt = 1;
  315. wsi->desc.sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  316. } else
  317. #endif
  318. {
  319. #ifdef LWS_WITH_IPV6
  320. if (wsi->ipv6)
  321. wsi->desc.sockfd = socket(AF_INET6, SOCK_STREAM, 0);
  322. else
  323. #endif
  324. wsi->desc.sockfd = socket(AF_INET, SOCK_STREAM, 0);
  325. }
  326. if (!lws_socket_is_valid(wsi->desc.sockfd)) {
  327. lwsl_warn("Unable to open socket\n");
  328. cce = "unable to open socket";
  329. goto oom4;
  330. }
  331. if (lws_plat_set_socket_options(wsi->vhost, wsi->desc.sockfd,
  332. #if defined(LWS_WITH_UNIX_SOCK)
  333. unix_skt)) {
  334. #else
  335. 0)) {
  336. #endif
  337. lwsl_err("Failed to set wsi socket options\n");
  338. compatible_close(wsi->desc.sockfd);
  339. cce = "set socket opts failed";
  340. goto oom4;
  341. }
  342. lwsi_set_state(wsi, LRS_WAITING_CONNECT);
  343. if (wsi->context->event_loop_ops->accept)
  344. if (wsi->context->event_loop_ops->accept(wsi)) {
  345. compatible_close(wsi->desc.sockfd);
  346. cce = "event loop accept failed";
  347. goto oom4;
  348. }
  349. if (__insert_wsi_socket_into_fds(wsi->context, wsi)) {
  350. compatible_close(wsi->desc.sockfd);
  351. cce = "insert wsi failed";
  352. goto oom4;
  353. }
  354. lws_change_pollfd(wsi, 0, LWS_POLLIN);
  355. /*
  356. * past here, we can't simply free the structs as error
  357. * handling as oom4 does. We have to run the whole close flow.
  358. */
  359. if (!wsi->protocol)
  360. wsi->protocol = &wsi->vhost->protocols[0];
  361. wsi->protocol->callback(wsi, LWS_CALLBACK_WSI_CREATE,
  362. wsi->user_space, NULL, 0);
  363. lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
  364. AWAITING_TIMEOUT);
  365. iface = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE);
  366. if (iface) {
  367. n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0,
  368. iface);
  369. if (n < 0) {
  370. cce = "unable to bind socket";
  371. goto failed;
  372. }
  373. }
  374. }
  375. #if defined(LWS_WITH_UNIX_SOCK)
  376. if (unix_skt) {
  377. psa = (const struct sockaddr *)&sau;
  378. n = sizeof(sau);
  379. } else
  380. #endif
  381. {
  382. #ifdef LWS_WITH_IPV6
  383. if (wsi->ipv6) {
  384. sa46.sa6.sin6_port = htons(port);
  385. n = sizeof(struct sockaddr_in6);
  386. psa = (const struct sockaddr *)&sa46;
  387. } else
  388. #endif
  389. {
  390. sa46.sa4.sin_port = htons(port);
  391. n = sizeof(struct sockaddr);
  392. psa = (const struct sockaddr *)&sa46;
  393. }
  394. }
  395. if (connect(wsi->desc.sockfd, (const struct sockaddr *)psa, n) == -1 ||
  396. LWS_ERRNO == LWS_EISCONN) {
  397. if (LWS_ERRNO == LWS_EALREADY ||
  398. LWS_ERRNO == LWS_EINPROGRESS ||
  399. LWS_ERRNO == LWS_EWOULDBLOCK
  400. #ifdef _WIN32
  401. || LWS_ERRNO == WSAEINVAL
  402. #endif
  403. ) {
  404. lwsl_client("nonblocking connect retry (errno = %d)\n",
  405. LWS_ERRNO);
  406. if (lws_plat_check_connection_error(wsi)) {
  407. cce = "socket connect failed";
  408. goto failed;
  409. }
  410. /*
  411. * must do specifically a POLLOUT poll to hear
  412. * about the connect completion
  413. */
  414. if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
  415. cce = "POLLOUT set failed";
  416. goto failed;
  417. }
  418. return wsi;
  419. }
  420. if (LWS_ERRNO != LWS_EISCONN) {
  421. lwsl_notice("Connect failed errno=%d\n", LWS_ERRNO);
  422. cce = "connect failed";
  423. goto failed;
  424. }
  425. }
  426. lwsl_client("connected\n");
  427. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  428. /* we are connected to server, or proxy */
  429. /* http proxy */
  430. if (wsi->vhost->http.http_proxy_port) {
  431. /*
  432. * OK from now on we talk via the proxy, so connect to that
  433. *
  434. * (will overwrite existing pointer,
  435. * leaving old string/frag there but unreferenced)
  436. */
  437. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
  438. wsi->vhost->http.http_proxy_address))
  439. goto failed;
  440. wsi->c_port = wsi->vhost->http.http_proxy_port;
  441. n = send(wsi->desc.sockfd, (char *)pt->serv_buf, (int)plen,
  442. MSG_NOSIGNAL);
  443. if (n < 0) {
  444. lwsl_debug("ERROR writing to proxy socket\n");
  445. cce = "proxy write failed";
  446. goto failed;
  447. }
  448. lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
  449. AWAITING_TIMEOUT);
  450. lwsi_set_state(wsi, LRS_WAITING_PROXY_REPLY);
  451. return wsi;
  452. }
  453. #endif
  454. #if defined(LWS_WITH_SOCKS5)
  455. /* socks proxy */
  456. else if (wsi->vhost->socks_proxy_port) {
  457. n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen,
  458. MSG_NOSIGNAL);
  459. if (n < 0) {
  460. lwsl_debug("ERROR writing socks greeting\n");
  461. cce = "socks write failed";
  462. goto failed;
  463. }
  464. lws_set_timeout(wsi,
  465. PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY,
  466. AWAITING_TIMEOUT);
  467. lwsi_set_state(wsi, LRS_WAITING_SOCKS_GREETING_REPLY);
  468. return wsi;
  469. }
  470. #endif
  471. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  472. send_hs:
  473. if (wsi_piggyback &&
  474. !lws_dll_is_null(&wsi->dll_client_transaction_queue)) {
  475. /*
  476. * We are pipelining on an already-established connection...
  477. * we can skip tls establishment.
  478. */
  479. lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2);
  480. /*
  481. * we can't send our headers directly, because they have to
  482. * be sent when the parent is writeable. The parent will check
  483. * for anybody on his client transaction queue that is in
  484. * LRS_H1C_ISSUE_HANDSHAKE2, and let them write.
  485. *
  486. * If we are trying to do this too early, before the master
  487. * connection has written his own headers, then it will just
  488. * wait in the queue until it's possible to send them.
  489. */
  490. lws_callback_on_writable(wsi_piggyback);
  491. lwsl_info("%s: wsi %p: waiting to send hdrs (par state 0x%x)\n",
  492. __func__, wsi, lwsi_state(wsi_piggyback));
  493. } else {
  494. lwsl_info("%s: wsi %p: client creating own connection\n",
  495. __func__, wsi);
  496. /* we are making our own connection */
  497. lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE);
  498. /*
  499. * provoke service to issue the handshake directly.
  500. *
  501. * we need to do it this way because in the proxy case, this is
  502. * the next state and executed only if and when we get a good
  503. * proxy response inside the state machine... but notice in
  504. * SSL case this may not have sent anything yet with 0 return,
  505. * and won't until many retries from main loop. To stop that
  506. * becoming endless, cover with a timeout.
  507. */
  508. lws_set_timeout(wsi, PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE,
  509. AWAITING_TIMEOUT);
  510. pfd.fd = wsi->desc.sockfd;
  511. pfd.events = LWS_POLLIN;
  512. pfd.revents = LWS_POLLIN;
  513. n = lws_service_fd(context, &pfd);
  514. if (n < 0) {
  515. cce = "first service failed";
  516. goto failed;
  517. }
  518. if (n) /* returns 1 on failure after closing wsi */
  519. return NULL;
  520. }
  521. #endif
  522. return wsi;
  523. oom4:
  524. if (lwsi_role_client(wsi) /* && lwsi_state_est(wsi) */) {
  525. wsi->protocol->callback(wsi,
  526. LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
  527. wsi->user_space, (void *)cce, strlen(cce));
  528. wsi->already_did_cce = 1;
  529. }
  530. /* take care that we might be inserted in fds already */
  531. if (wsi->position_in_fds_table != LWS_NO_FDS_POS)
  532. goto failed1;
  533. /*
  534. * We can't be an active client connection any more, if we thought
  535. * that was what we were going to be doing. It should be if we are
  536. * failing by oom4 path, we are still called by
  537. * lws_client_connect_via_info() and will be returning NULL to that,
  538. * so nobody else should have had a chance to queue on us.
  539. */
  540. {
  541. struct lws_vhost *vhost = wsi->vhost;
  542. lws_vhost_lock(vhost);
  543. __lws_free_wsi(wsi);
  544. lws_vhost_unlock(vhost);
  545. }
  546. return NULL;
  547. failed:
  548. wsi->protocol->callback(wsi,
  549. LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
  550. wsi->user_space, (void *)cce, strlen(cce));
  551. wsi->already_did_cce = 1;
  552. failed1:
  553. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect2");
  554. return NULL;
  555. }
  556. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  557. /**
  558. * lws_client_reset() - retarget a connected wsi to start over with a new
  559. * connection (ie, redirect)
  560. * this only works if still in HTTP, ie, not upgraded yet
  561. * wsi: connection to reset
  562. * address: network address of the new server
  563. * port: port to connect to
  564. * path: uri path to connect to on the new server
  565. * host: host header to send to the new server
  566. */
  567. LWS_VISIBLE struct lws *
  568. lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
  569. const char *path, const char *host)
  570. {
  571. char origin[300] = "", protocol[300] = "", method[32] = "",
  572. iface[16] = "", alpn[32] = "", *p;
  573. struct lws *wsi = *pwsi;
  574. if (wsi->redirects == 3) {
  575. lwsl_err("%s: Too many redirects\n", __func__);
  576. return NULL;
  577. }
  578. wsi->redirects++;
  579. p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN);
  580. if (p)
  581. lws_strncpy(origin, p, sizeof(origin));
  582. p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
  583. if (p)
  584. lws_strncpy(protocol, p, sizeof(protocol));
  585. p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
  586. if (p)
  587. lws_strncpy(method, p, sizeof(method));
  588. p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE);
  589. if (p)
  590. lws_strncpy(iface, p, sizeof(iface));
  591. p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ALPN);
  592. if (p)
  593. lws_strncpy(alpn, p, sizeof(alpn));
  594. lwsl_info("redirect ads='%s', port=%d, path='%s', ssl = %d\n",
  595. address, port, path, ssl);
  596. /* close the connection by hand */
  597. #if defined(LWS_WITH_TLS)
  598. lws_ssl_close(wsi);
  599. #endif
  600. __remove_wsi_socket_from_fds(wsi);
  601. if (wsi->context->event_loop_ops->close_handle_manually)
  602. wsi->context->event_loop_ops->close_handle_manually(wsi);
  603. else
  604. compatible_close(wsi->desc.sockfd);
  605. #if defined(LWS_WITH_TLS)
  606. wsi->tls.use_ssl = ssl;
  607. #else
  608. if (ssl) {
  609. lwsl_err("%s: not configured for ssl\n", __func__);
  610. return NULL;
  611. }
  612. #endif
  613. wsi->desc.sockfd = LWS_SOCK_INVALID;
  614. lwsi_set_state(wsi, LRS_UNCONNECTED);
  615. wsi->protocol = NULL;
  616. wsi->pending_timeout = NO_PENDING_TIMEOUT;
  617. wsi->c_port = port;
  618. wsi->hdr_parsing_completed = 0;
  619. _lws_header_table_reset(wsi->http.ah);
  620. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
  621. return NULL;
  622. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
  623. return NULL;
  624. if (origin[0])
  625. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
  626. origin))
  627. return NULL;
  628. if (protocol[0])
  629. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
  630. protocol))
  631. return NULL;
  632. if (method[0])
  633. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
  634. method))
  635. return NULL;
  636. if (iface[0])
  637. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE,
  638. iface))
  639. return NULL;
  640. if (alpn[0])
  641. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ALPN,
  642. alpn))
  643. return NULL;
  644. origin[0] = '/';
  645. strncpy(&origin[1], path, sizeof(origin) - 2);
  646. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, origin))
  647. return NULL;
  648. *pwsi = lws_client_connect_2(wsi);
  649. return *pwsi;
  650. }
  651. #if defined(LWS_WITH_HTTP_PROXY) && defined(LWS_WITH_HUBBUB)
  652. hubbub_error
  653. html_parser_cb(const hubbub_token *token, void *pw)
  654. {
  655. struct lws_rewrite *r = (struct lws_rewrite *)pw;
  656. char buf[1024], *start = buf + LWS_PRE, *p = start,
  657. *end = &buf[sizeof(buf) - 1];
  658. size_t i;
  659. switch (token->type) {
  660. case HUBBUB_TOKEN_DOCTYPE:
  661. p += lws_snprintf(p, end - p, "<!DOCTYPE %.*s %s ",
  662. (int) token->data.doctype.name.len,
  663. token->data.doctype.name.ptr,
  664. token->data.doctype.force_quirks ?
  665. "(force-quirks) " : "");
  666. if (token->data.doctype.public_missing)
  667. lwsl_debug("\tpublic: missing\n");
  668. else
  669. p += lws_snprintf(p, end - p, "PUBLIC \"%.*s\"\n",
  670. (int) token->data.doctype.public_id.len,
  671. token->data.doctype.public_id.ptr);
  672. if (token->data.doctype.system_missing)
  673. lwsl_debug("\tsystem: missing\n");
  674. else
  675. p += lws_snprintf(p, end - p, " \"%.*s\">\n",
  676. (int) token->data.doctype.system_id.len,
  677. token->data.doctype.system_id.ptr);
  678. break;
  679. case HUBBUB_TOKEN_START_TAG:
  680. p += lws_snprintf(p, end - p, "<%.*s", (int)token->data.tag.name.len,
  681. token->data.tag.name.ptr);
  682. /* (token->data.tag.self_closing) ?
  683. "(self-closing) " : "",
  684. (token->data.tag.n_attributes > 0) ?
  685. "attributes:" : "");
  686. */
  687. for (i = 0; i < token->data.tag.n_attributes; i++) {
  688. if (!hstrcmp(&token->data.tag.attributes[i].name, "href", 4) ||
  689. !hstrcmp(&token->data.tag.attributes[i].name, "action", 6) ||
  690. !hstrcmp(&token->data.tag.attributes[i].name, "src", 3)) {
  691. const char *pp = (const char *)token->data.tag.attributes[i].value.ptr;
  692. int plen = (int) token->data.tag.attributes[i].value.len;
  693. if (strncmp(pp, "http:", 5) && strncmp(pp, "https:", 6)) {
  694. if (!hstrcmp(&token->data.tag.attributes[i].value,
  695. r->from, r->from_len)) {
  696. pp += r->from_len;
  697. plen -= r->from_len;
  698. }
  699. p += lws_snprintf(p, end - p, " %.*s=\"%s/%.*s\"",
  700. (int) token->data.tag.attributes[i].name.len,
  701. token->data.tag.attributes[i].name.ptr,
  702. r->to, plen, pp);
  703. continue;
  704. }
  705. }
  706. p += lws_snprintf(p, end - p, " %.*s=\"%.*s\"",
  707. (int) token->data.tag.attributes[i].name.len,
  708. token->data.tag.attributes[i].name.ptr,
  709. (int) token->data.tag.attributes[i].value.len,
  710. token->data.tag.attributes[i].value.ptr);
  711. }
  712. p += lws_snprintf(p, end - p, ">");
  713. break;
  714. case HUBBUB_TOKEN_END_TAG:
  715. p += lws_snprintf(p, end - p, "</%.*s", (int) token->data.tag.name.len,
  716. token->data.tag.name.ptr);
  717. /*
  718. (token->data.tag.self_closing) ?
  719. "(self-closing) " : "",
  720. (token->data.tag.n_attributes > 0) ?
  721. "attributes:" : "");
  722. */
  723. for (i = 0; i < token->data.tag.n_attributes; i++) {
  724. p += lws_snprintf(p, end - p, " %.*s='%.*s'\n",
  725. (int) token->data.tag.attributes[i].name.len,
  726. token->data.tag.attributes[i].name.ptr,
  727. (int) token->data.tag.attributes[i].value.len,
  728. token->data.tag.attributes[i].value.ptr);
  729. }
  730. p += lws_snprintf(p, end - p, ">");
  731. break;
  732. case HUBBUB_TOKEN_COMMENT:
  733. p += lws_snprintf(p, end - p, "<!-- %.*s -->\n",
  734. (int) token->data.comment.len,
  735. token->data.comment.ptr);
  736. break;
  737. case HUBBUB_TOKEN_CHARACTER:
  738. if (token->data.character.len == 1) {
  739. if (*token->data.character.ptr == '<') {
  740. p += lws_snprintf(p, end - p, "&lt;");
  741. break;
  742. }
  743. if (*token->data.character.ptr == '>') {
  744. p += lws_snprintf(p, end - p, "&gt;");
  745. break;
  746. }
  747. if (*token->data.character.ptr == '&') {
  748. p += lws_snprintf(p, end - p, "&amp;");
  749. break;
  750. }
  751. }
  752. p += lws_snprintf(p, end - p, "%.*s", (int) token->data.character.len,
  753. token->data.character.ptr);
  754. break;
  755. case HUBBUB_TOKEN_EOF:
  756. p += lws_snprintf(p, end - p, "\n");
  757. break;
  758. }
  759. if (user_callback_handle_rxflow(r->wsi->protocol->callback,
  760. r->wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ,
  761. r->wsi->user_space, start, p - start))
  762. return -1;
  763. return HUBBUB_OK;
  764. }
  765. #endif
  766. #endif
  767. struct lws *
  768. lws_http_client_connect_via_info2(struct lws *wsi)
  769. {
  770. struct client_info_stash *stash = wsi->stash;
  771. if (!stash)
  772. return wsi;
  773. /*
  774. * we're not necessarily in a position to action these right away,
  775. * stash them... we only need during connect phase so into a temp
  776. * allocated stash
  777. */
  778. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
  779. stash->address))
  780. goto bail1;
  781. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash->path))
  782. goto bail1;
  783. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, stash->host))
  784. goto bail1;
  785. if (stash->origin)
  786. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
  787. stash->origin))
  788. goto bail1;
  789. /*
  790. * this is a list of protocols we tell the server we're okay with
  791. * stash it for later when we compare server response with it
  792. */
  793. if (stash->protocol)
  794. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
  795. stash->protocol))
  796. goto bail1;
  797. if (stash->method)
  798. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
  799. stash->method))
  800. goto bail1;
  801. if (stash->iface)
  802. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE,
  803. stash->iface))
  804. goto bail1;
  805. if (stash->alpn)
  806. if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ALPN,
  807. stash->alpn))
  808. goto bail1;
  809. #if defined(LWS_WITH_SOCKS5)
  810. if (!wsi->vhost->socks_proxy_port)
  811. lws_client_stash_destroy(wsi);
  812. #endif
  813. wsi->context->count_wsi_allocated++;
  814. return lws_client_connect_2(wsi);
  815. bail1:
  816. #if defined(LWS_WITH_SOCKS5)
  817. if (!wsi->vhost->socks_proxy_port)
  818. lws_free_set_NULL(wsi->stash);
  819. #endif
  820. return NULL;
  821. }
  822. #if defined(LWS_WITH_SOCKS5)
  823. void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
  824. ssize_t *msg_len)
  825. {
  826. struct lws_context *context = wsi->context;
  827. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  828. ssize_t len = 0, n, passwd_len;
  829. short net_num;
  830. char *p;
  831. switch (type) {
  832. case SOCKS_MSG_GREETING:
  833. /* socks version, version 5 only */
  834. pt->serv_buf[len++] = SOCKS_VERSION_5;
  835. /* number of methods */
  836. pt->serv_buf[len++] = 2;
  837. /* username password method */
  838. pt->serv_buf[len++] = SOCKS_AUTH_USERNAME_PASSWORD;
  839. /* no authentication method */
  840. pt->serv_buf[len++] = SOCKS_AUTH_NO_AUTH;
  841. break;
  842. case SOCKS_MSG_USERNAME_PASSWORD:
  843. n = strlen(wsi->vhost->socks_user);
  844. passwd_len = strlen(wsi->vhost->socks_password);
  845. /* the subnegotiation version */
  846. pt->serv_buf[len++] = SOCKS_SUBNEGOTIATION_VERSION_1;
  847. /* length of the user name */
  848. pt->serv_buf[len++] = n;
  849. /* user name */
  850. lws_strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_user,
  851. context->pt_serv_buf_size - len + 1);
  852. len += n;
  853. /* length of the password */
  854. pt->serv_buf[len++] = passwd_len;
  855. /* password */
  856. lws_strncpy((char *)&pt->serv_buf[len],
  857. wsi->vhost->socks_password,
  858. context->pt_serv_buf_size - len + 1);
  859. len += passwd_len;
  860. break;
  861. case SOCKS_MSG_CONNECT:
  862. p = (char*)&net_num;
  863. /* socks version */
  864. pt->serv_buf[len++] = SOCKS_VERSION_5;
  865. /* socks command */
  866. pt->serv_buf[len++] = SOCKS_COMMAND_CONNECT;
  867. /* reserved */
  868. pt->serv_buf[len++] = 0;
  869. /* address type */
  870. pt->serv_buf[len++] = SOCKS_ATYP_DOMAINNAME;
  871. /* skip length, we fill it in at the end */
  872. n = len++;
  873. /* the address we tell SOCKS proxy to connect to */
  874. lws_strncpy((char *)&(pt->serv_buf[len]), wsi->stash->address,
  875. context->pt_serv_buf_size - len + 1);
  876. len += strlen(wsi->stash->address);
  877. net_num = htons(wsi->c_port);
  878. /* the port we tell SOCKS proxy to connect to */
  879. pt->serv_buf[len++] = p[0];
  880. pt->serv_buf[len++] = p[1];
  881. /* the length of the address, excluding port */
  882. pt->serv_buf[n] = strlen(wsi->stash->address);
  883. break;
  884. default:
  885. return;
  886. }
  887. *msg_len = len;
  888. }
  889. #endif