Skip to content
Snippets Groups Projects
client-handshake.c 31.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	if (i->pwsi)
    		*i->pwsi = wsi;
    
    
    	/* if we went on the waiting list, no probs just return the wsi
    	 * when we get the ah, now or later, he will call
    
    	 * lws_client_connect_via_info2() below.
    
    	if (lws_header_table_attach(wsi, 0) < 0) {
    		/*
    		 * if we failed here, the connection is already closed
    		 * and freed.
    		 */
    
    	if (i->parent_wsi) {
    		lwsl_info("%s: created child %p of parent %p\n", __func__,
    				wsi, i->parent_wsi);
    		wsi->parent = i->parent_wsi;
    		wsi->sibling_list = i->parent_wsi->child_list;
    		i->parent_wsi->child_list = wsi;
    	}
    
    Andy Green's avatar
    Andy Green committed
    #ifdef LWS_WITH_HTTP_PROXY
    
    Andy Green's avatar
    Andy Green committed
    	if (i->uri_replace_to)
    		wsi->rw = lws_rewrite_create(wsi, html_parser_cb,
    					     i->uri_replace_from,
    					     i->uri_replace_to);
    
    Andy Green's avatar
    Andy Green committed
    #endif
    
    Andy Green's avatar
    Andy Green committed
    
    
    bail1:
    	lws_client_stash_destroy(wsi);
    
    
    	if (i->pwsi)
    		*i->pwsi = NULL;
    
    
    	return NULL;
    }
    
    struct lws *
    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);
    
    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;