Skip to content
Snippets Groups Projects
client-handshake.c 30.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • lws_client_connect_via_info2(struct lws *wsi)
    {
    
    Andy Green's avatar
    Andy Green committed
    	struct client_info_stash *stash = wsi->stash;
    
    
    	/*
    	 * we're not necessarily in a position to action these right away,
    	 * stash them... we only need during connect phase so u.hdr is fine
    	 */
    
    	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
    				  stash->address))
    
    	/* these only need u.hdr lifetime as well */
    
    	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash->path))
    
    	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, stash->host))
    
    	if (stash->origin)
    
    		if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
    					  stash->origin))
    
    			goto bail1;
    	/*
    	 * this is a list of protocols we tell the server we're okay with
    	 * stash it for later when we compare server response with it
    	 */
    
    	if (stash->protocol)
    
    Andy Green's avatar
    Andy Green committed
    		if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
    
    	if (stash->method)
    
    		if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
    					  stash->method))
    			goto bail1;
    
    	if (stash->iface)
    
    		if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE,
    					  stash->iface))
    			goto bail1;
    
    #if defined(LWS_WITH_SOCKS5)
    	if (!wsi->vhost->socks_proxy_port)
    
    		lws_client_stash_destroy(wsi);
    
    	 * Check with each extension if it is able to route and proxy this
    	 * connection for us.  For example, an extension like x-google-mux
    	 * can handle this and then we don't need an actual socket for this
    	 * connection.
    
    	if (lws_ext_cb_all_exts(wsi->context, wsi,
    				LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION,
    				(void *)stash->address,
    
    				wsi->c_port) > 0) {
    
    		lwsl_client("lws_client_connect: ext handling conn\n");
    
    		lws_set_timeout(wsi,
    
    Andy Green's avatar
    Andy Green committed
    			PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
    
    Andy Green's avatar
    Andy Green committed
    			        AWAITING_TIMEOUT);
    
    Andy Green's avatar
    Andy Green committed
    		wsi->mode = LWSCM_WSCL_WAITING_EXTENSION_CONNECT;
    
    	lwsl_client("lws_client_connect: direct conn\n");
    
    Andy Green's avatar
    Andy Green committed
    	wsi->context->count_wsi_allocated++;
    
    
    	return lws_client_connect_2(wsi);
    
    #if defined(LWS_WITH_SOCKS5)
    	if (!wsi->vhost->socks_proxy_port)
    
    Andy Green's avatar
    Andy Green committed
    		lws_free_set_NULL(wsi->stash);
    
    Andy Green's avatar
    Andy Green committed
    lws_client_connect_extended(struct lws_context *context, const char *address,
    			    int port, int ssl_connection, const char *path,
    			    const char *host, const char *origin,
    			    const char *protocol, int ietf_version_or_minus_one,
    			    void *userdata)
    
    	struct lws_client_connect_info i;
    
    	memset(&i, 0, sizeof(i));
    
    	i.context = context;
    	i.address = address;
    	i.port = port;
    	i.ssl_connection = ssl_connection;
    	i.path = path;
    	i.host = host;
    	i.origin = origin;
    	i.protocol = protocol;
    	i.ietf_version_or_minus_one = ietf_version_or_minus_one;
    	i.userdata = userdata;
    
    
    Andy Green's avatar
    Andy Green committed
    	return lws_client_connect_via_info(&i);
    
    LWS_VISIBLE struct lws *
    lws_client_connect(struct lws_context *context, const char *address,
    			    int port, int ssl_connection, const char *path,
    			    const char *host, const char *origin,
    			    const char *protocol, int ietf_version_or_minus_one)
    {
    
    	struct lws_client_connect_info i;
    
    	memset(&i, 0, sizeof(i));
    
    	i.context = context;
    	i.address = address;
    	i.port = port;
    	i.ssl_connection = ssl_connection;
    	i.path = path;
    	i.host = host;
    	i.origin = origin;
    	i.protocol = protocol;
    	i.ietf_version_or_minus_one = ietf_version_or_minus_one;
    	i.userdata = NULL;
    
    	return lws_client_connect_via_info(&i);
    
    Andy Green's avatar
    Andy Green committed
    }
    
    #if defined(LWS_WITH_SOCKS5)
    void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
    
    Andy Green's avatar
    Andy Green committed
    			ssize_t *msg_len)
    
    {
    	struct lws_context *context = wsi->context;
    	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
    
    	ssize_t len = 0, n, passwd_len;
    	short net_num;
    	char *p;
    
    	switch (type) {
    	case SOCKS_MSG_GREETING:
    
    		/* socks version, version 5 only */
    		pt->serv_buf[len++] = SOCKS_VERSION_5;
    		/* number of methods */
    		pt->serv_buf[len++] = 2;
    		/* username password method */
    		pt->serv_buf[len++] = SOCKS_AUTH_USERNAME_PASSWORD;
    		/* no authentication method */
    		pt->serv_buf[len++] = SOCKS_AUTH_NO_AUTH;
    
    	case SOCKS_MSG_USERNAME_PASSWORD:
    		n = strlen(wsi->vhost->socks_user);
    
    		passwd_len = strlen(wsi->vhost->socks_password);
    
    		/* the subnegotiation version */
    		pt->serv_buf[len++] = SOCKS_SUBNEGOTIATION_VERSION_1;
    		/* length of the user name */
    
    		pt->serv_buf[len++] = n;
    
    		/* user name */
    
    Andy Green's avatar
    Andy Green committed
    		lws_strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_user,
    			context->pt_serv_buf_size - len + 1);
    
    		len += n;
    
    		/* length of the password */
    		pt->serv_buf[len++] = passwd_len;
    		/* password */
    
    Andy Green's avatar
    Andy Green committed
    		lws_strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_password,
    			context->pt_serv_buf_size - len + 1);
    
    		len += passwd_len;
    
    		break;
    
    	case SOCKS_MSG_CONNECT:
    		p = (char*)&net_num;
    
    
    		/* socks version */
    		pt->serv_buf[len++] = SOCKS_VERSION_5;
    		/* socks command */
    		pt->serv_buf[len++] = SOCKS_COMMAND_CONNECT;
    		/* reserved */
    		pt->serv_buf[len++] = 0;
    		/* address type */
    		pt->serv_buf[len++] = SOCKS_ATYP_DOMAINNAME;
    
    		/* skip length, we fill it in at the end */
    		n = len++;
    
    		/* the address we tell SOCKS proxy to connect to */
    
    Andy Green's avatar
    Andy Green committed
    		lws_strncpy((char *)&(pt->serv_buf[len]), wsi->stash->address,
    			context->pt_serv_buf_size - len + 1);
    
    Andy Green's avatar
    Andy Green committed
    		len += strlen(wsi->stash->address);
    
    		net_num = htons(wsi->c_port);
    
    		/* the port we tell SOCKS proxy to connect to */
    
    		pt->serv_buf[len++] = p[0];
    		pt->serv_buf[len++] = p[1];
    
    		/* the length of the address, excluding port */
    
    Andy Green's avatar
    Andy Green committed
    		pt->serv_buf[n] = strlen(wsi->stash->address);
    
    		break;
    		
    	default:
    		return;