1/* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com> 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 25#include "private-lib-core.h" 26 27struct lws * 28lws_client_connect_4_established(struct lws *wsi, struct lws *wsi_piggyback, 29 ssize_t plen) 30{ 31#if defined(LWS_CLIENT_HTTP_PROXYING) 32 struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi]; 33#endif 34 const char *meth; 35 struct lws_pollfd pfd; 36 const char *cce = ""; 37 int n, m, rawish = 0; 38 39 meth = lws_wsi_client_stash_item(wsi, CIS_METHOD, 40 _WSI_TOKEN_CLIENT_METHOD); 41 42 if (meth && (!strcmp(meth, "RAW") 43#if defined(LWS_ROLE_MQTT) 44 || !strcmp(meth, "MQTT") 45#endif 46 )) 47 rawish = 1; 48 49 if (wsi_piggyback) 50 goto send_hs; 51 52#if defined(LWS_CLIENT_HTTP_PROXYING) 53#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 54 /* we are connected to server, or proxy */ 55 56 /* http proxy */ 57 if (wsi->a.vhost->http.http_proxy_port) { 58 const char *cpa; 59 60 cpa = lws_wsi_client_stash_item(wsi, CIS_ADDRESS, 61 _WSI_TOKEN_CLIENT_PEER_ADDRESS); 62 if (!cpa) 63 goto failed; 64 65 lwsl_wsi_info(wsi, "going via proxy"); 66 67 plen = lws_snprintf((char *)pt->serv_buf, 256, 68 "CONNECT %s:%u HTTP/1.1\x0d\x0a" 69 "Host: %s:%u\x0d\x0a" 70 "User-agent: lws\x0d\x0a", cpa, wsi->ocport, 71 cpa, wsi->ocport); 72 73#if defined(LWS_WITH_HTTP_BASIC_AUTH) 74 if (wsi->a.vhost->proxy_basic_auth_token[0]) 75 plen += lws_snprintf((char *)pt->serv_buf + plen, 256, 76 "Proxy-authorization: basic %s\x0d\x0a", 77 wsi->a.vhost->proxy_basic_auth_token); 78#endif 79 80 plen += lws_snprintf((char *)pt->serv_buf + plen, 5, 81 "\x0d\x0a"); 82 83 /* lwsl_hexdump_notice(pt->serv_buf, plen); */ 84 85 /* 86 * OK from now on we talk via the proxy, so connect to that 87 */ 88 if (wsi->stash) 89 wsi->stash->cis[CIS_ADDRESS] = 90 wsi->a.vhost->http.http_proxy_address; 91 else 92 if (lws_hdr_simple_create(wsi, 93 _WSI_TOKEN_CLIENT_PEER_ADDRESS, 94 wsi->a.vhost->http.http_proxy_address)) 95 goto failed; 96 wsi->c_port = (uint16_t)wsi->a.vhost->http.http_proxy_port; 97 98 n = (int)send(wsi->desc.sockfd, (char *)pt->serv_buf, 99 (unsigned int)plen, 100 MSG_NOSIGNAL); 101 if (n < 0) { 102 lwsl_wsi_debug(wsi, "ERROR writing to proxy socket"); 103 cce = "proxy write failed"; 104 goto failed; 105 } 106 107 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, 108 (int)wsi->a.context->timeout_secs); 109 110 wsi->conn_port = wsi->c_port; 111 lwsi_set_state(wsi, LRS_WAITING_PROXY_REPLY); 112 113 return wsi; 114 } 115#endif 116#endif 117 118 /* coverity */ 119 if (!wsi->a.protocol) 120 return NULL; 121 122#if defined(LWS_WITH_SOCKS5) 123 if (lwsi_state(wsi) != LRS_ESTABLISHED) 124 switch (lws_socks5c_greet(wsi, &cce)) { 125 case -1: 126 goto failed; 127 case 1: 128 return wsi; 129 default: 130 break; 131 } 132#endif 133 134#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 135send_hs: 136 137 if (wsi_piggyback && 138 !lws_dll2_is_detached(&wsi->dll2_cli_txn_queue)) { 139 /* 140 * We are pipelining on an already-established connection... 141 * we can skip tls establishment. 142 * 143 * Set these queued guys to a state where they won't actually 144 * send their headers until we decide later. 145 */ 146 147 lwsi_set_state(wsi, LRS_H2_WAITING_TO_SEND_HEADERS); 148 149 /* 150 * we can't send our headers directly, because they have to 151 * be sent when the parent is writeable. The parent will check 152 * for anybody on his client transaction queue that is in 153 * LRS_H1C_ISSUE_HANDSHAKE2, and let them write. 154 * 155 * If we are trying to do this too early, before the network 156 * connection has written his own headers, then it will just 157 * wait in the queue until it's possible to send them. 158 */ 159 lws_callback_on_writable(wsi_piggyback); 160 161 lwsl_wsi_info(wsi, "waiting to send hdrs (par state 0x%x)", 162 lwsi_state(wsi_piggyback)); 163 } else { 164 lwsl_wsi_info(wsi, "%s %s client created own conn " 165 "(raw %d) vh %s st 0x%x", 166 wsi->role_ops->name, wsi->a.protocol->name, rawish, 167 wsi->a.vhost->name, lwsi_state(wsi)); 168 169 /* we are making our own connection */ 170 171 if (!rawish 172#if defined(LWS_WITH_TLS) 173 // && (!(wsi->tls.use_ssl & LCCSCF_USE_SSL) || wsi->tls.ssl) 174#endif 175 ) { 176 177 if (lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2) 178 lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE); 179 } else { 180 /* for a method = "RAW" connection, this makes us 181 * established */ 182 183#if defined(LWS_WITH_TLS)// && !defined(LWS_WITH_MBEDTLS) 184 185 /* we have connected if we got here */ 186 187 if (lwsi_state(wsi) == LRS_WAITING_CONNECT && 188 (wsi->tls.use_ssl & LCCSCF_USE_SSL)) { 189 int result; 190 191 //lwsi_set_state(wsi, LRS_WAITING_SSL); 192 193 /* 194 * We can retry this... just cook the SSL BIO 195 * the first time 196 */ 197 198 result = lws_client_create_tls(wsi, &cce, 1); 199 switch (result) { 200 case CCTLS_RETURN_DONE: 201 break; 202 case CCTLS_RETURN_RETRY: 203 lwsl_wsi_debug(wsi, "create_tls RETRY"); 204 return wsi; 205 default: 206 lwsl_wsi_debug(wsi, "create_tls FAIL"); 207 goto failed; 208 } 209 210 /* 211 * We succeeded to negotiate a new client tls 212 * tunnel. If it's h2 alpn, we have arranged 213 * to send the h2 prefix and set our state to 214 * LRS_H2_WAITING_TO_SEND_HEADERS already. 215 */ 216 217 lwsl_wsi_notice(wsi, "tls established st 0x%x, " 218 "client_h2_alpn %d", lwsi_state(wsi), 219 wsi->client_h2_alpn); 220 221 if (lwsi_state(wsi) != 222 LRS_H2_WAITING_TO_SEND_HEADERS) 223 lwsi_set_state(wsi, 224 LRS_H1C_ISSUE_HANDSHAKE2); 225 lws_set_timeout(wsi, 226 PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, 227 (int)wsi->a.context->timeout_secs); 228#if 0 229 /* ensure pollin enabled */ 230 if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) 231 lwsl_wsi_notice(wsi, 232 "unable to set POLLIN"); 233#endif 234 235 goto provoke_service; 236 } 237#endif 238 239 /* clear his established timeout */ 240 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); 241 242 m = wsi->role_ops->adoption_cb[0]; 243 if (m) { 244 n = user_callback_handle_rxflow( 245 wsi->a.protocol->callback, wsi, 246 (enum lws_callback_reasons)m, 247 wsi->user_space, NULL, 0); 248 if (n < 0) { 249 lwsl_wsi_info(wsi, "RAW_PROXY_CLI_ADOPT err"); 250 goto failed; 251 } 252 } 253 254 /* service.c pollout processing wants this */ 255 wsi->hdr_parsing_completed = 1; 256#if defined(LWS_ROLE_MQTT) 257 if (meth && !strcmp(meth, "MQTT")) { 258#if defined(LWS_WITH_TLS) 259 if (wsi->tls.use_ssl & LCCSCF_USE_SSL) { 260 lwsi_set_state(wsi, LRS_WAITING_SSL); 261 return wsi; 262 } 263#endif 264 lwsl_wsi_info(wsi, "settings LRS_MQTTC_IDLE"); 265 lwsi_set_state(wsi, LRS_MQTTC_IDLE); 266 267 /* 268 * provoke service to issue the CONNECT 269 * directly. 270 */ 271 lws_set_timeout(wsi, 272 PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, 273 (int)wsi->a.context->timeout_secs); 274 275 assert(lws_socket_is_valid(wsi->desc.sockfd)); 276 277 pfd.fd = wsi->desc.sockfd; 278 pfd.events = LWS_POLLIN; 279 pfd.revents = LWS_POLLOUT; 280 281 lwsl_wsi_info(wsi, "going to service fd"); 282 n = lws_service_fd(wsi->a.context, &pfd); 283 if (n < 0) { 284 cce = "first service failed"; 285 goto failed; 286 } 287 if (n) 288 /* returns 1 on fail after close wsi */ 289 return NULL; 290 return wsi; 291 } 292#endif 293 lwsl_wsi_info(wsi, "setting ESTABLISHED"); 294 lwsi_set_state(wsi, LRS_ESTABLISHED); 295 296 return wsi; 297 } 298 299 /* 300 * provoke service to issue the handshake directly. 301 * 302 * we need to do it this way because in the proxy case, this is 303 * the next state and executed only if and when we get a good 304 * proxy response inside the state machine... but notice in 305 * SSL case this may not have sent anything yet with 0 return, 306 * and won't until many retries from main loop. To stop that 307 * becoming endless, cover with a timeout. 308 */ 309#if defined(LWS_WITH_TLS) //&& !defined(LWS_WITH_MBEDTLS) 310provoke_service: 311#endif 312 lws_set_timeout(wsi, PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, 313 (int)wsi->a.context->timeout_secs); 314 315 assert(lws_socket_is_valid(wsi->desc.sockfd)); 316 317 pfd.fd = wsi->desc.sockfd; 318 pfd.events = LWS_POLLIN; 319 pfd.revents = LWS_POLLIN; 320 321 n = lws_service_fd(wsi->a.context, &pfd); 322 if (n < 0) { 323 cce = "first service failed"; 324 goto failed; 325 } 326 if (n) /* returns 1 on failure after closing wsi */ 327 return NULL; 328 } 329#endif 330 return wsi; 331 332failed: 333 lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce)); 334 335 lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect4"); 336 337 return NULL; 338} 339