Esempio n. 1
0
File: pollfd.c Progetto: 5ouya/raspC
int
insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)
{
	struct lws_pollargs pa = { wsi->sock, LWS_POLLIN, 0 };
	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
	int ret = 0;
#ifndef LWS_NO_SERVER
	struct lws_pollargs pa1;
#endif

	lwsl_debug("%s: %p: tsi=%d, sock=%d, pos-in-fds=%d\n",
		  __func__, wsi, wsi->tsi, wsi->sock, pt->fds_count);

	if ((unsigned int)pt->fds_count >= context->fd_limit_per_thread) {
		lwsl_err("Too many fds (%d)\n", context->max_fds);
		return 1;
	}

#if !defined(_WIN32) && !defined(MBED_OPERATORS)
	if (wsi->sock >= context->max_fds) {
		lwsl_err("Socket fd %d is too high (%d)\n",
			 wsi->sock, context->max_fds);
		return 1;
	}
#endif

	assert(wsi);
	assert(lws_socket_is_valid(wsi->sock));

	if (context->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,
					   wsi->user_space, (void *) &pa, 1))
		return -1;

	lws_pt_lock(pt);
	pt->count_conns++;
	insert_wsi(context, wsi);
	wsi->position_in_fds_table = pt->fds_count;
	pt->fds[pt->fds_count].fd = wsi->sock;
	pt->fds[pt->fds_count].events = LWS_POLLIN;
	pa.events = pt->fds[pt->fds_count].events;

	lws_plat_insert_socket_into_fds(context, wsi);

	/* external POLL support via protocol 0 */
	if (context->protocols[0].callback(wsi, LWS_CALLBACK_ADD_POLL_FD,
					   wsi->user_space, (void *) &pa, 0))
		ret =  -1;
#ifndef LWS_NO_SERVER
	/* if no more room, defeat accepts on this thread */
	if ((unsigned int)pt->fds_count == context->fd_limit_per_thread - 1)
		_lws_change_pollfd(pt->wsi_listening, LWS_POLLIN, 0, &pa1);
#endif
	lws_pt_unlock(pt);

	if (context->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,
					   wsi->user_space, (void *)&pa, 1))
		ret = -1;

	return ret;
}
Esempio n. 2
0
int
insert_wsi_socket_into_fds(struct libwebsocket_context *context,
						       struct libwebsocket *wsi)
{
	struct libwebsocket_pollargs pa = { wsi->sock, LWS_POLLIN, 0 };

	if (context->fds_count >= context->max_fds) {
		lwsl_err("Too many fds (%d)\n", context->max_fds);
		return 1;
	}

#if !defined(_WIN32) && !defined(MBED_OPERATORS)
	if (wsi->sock >= context->max_fds) {
		lwsl_err("Socket fd %d is too high (%d)\n",
						wsi->sock, context->max_fds);
		return 1;
	}
#endif

	assert(wsi);
	assert(lws_socket_is_valid(wsi->sock));

//	lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n",
//					    wsi, wsi->sock, context->fds_count);

	if (context->protocols[0].callback(context, wsi,
	    LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0))
		return -1;

	insert_wsi(context, wsi);
	wsi->position_in_fds_table = context->fds_count;
	context->fds[context->fds_count].fd = wsi->sock;
	context->fds[context->fds_count].events = LWS_POLLIN;
	
	lws_plat_insert_socket_into_fds(context, wsi);

	/* external POLL support via protocol 0 */
	if (context->protocols[0].callback(context, wsi,
	    LWS_CALLBACK_ADD_POLL_FD, wsi->user_space, (void *) &pa, 0))
		return -1;

	if (context->protocols[0].callback(context, wsi,
	    LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 0))
		return -1;

	return 0;
}
Esempio n. 3
0
int
insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)
{
	struct lws_pollargs pa = { wsi->sock, LWS_POLLIN, 0 };
	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];

	if ((unsigned int)pt->fds_count >= context->fd_limit_per_thread) {
		lwsl_err("Too many fds (%d)\n", context->max_fds);
		return 1;
	}

#if !defined(_WIN32) && !defined(MBED_OPERATORS)
	if (wsi->sock >= context->max_fds) {
		lwsl_err("Socket fd %d is too high (%d)\n",
			 wsi->sock, context->max_fds);
		return 1;
	}
#endif

	assert(wsi);
	assert(lws_socket_is_valid(wsi->sock));

	if (context->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,
					   wsi->user_space, (void *) &pa, 1))
		return -1;

	insert_wsi(context, wsi);
	wsi->position_in_fds_table = pt->fds_count;
	pt->fds[pt->fds_count].fd = wsi->sock;
	pt->fds[pt->fds_count].events = LWS_POLLIN;

	lws_plat_insert_socket_into_fds(context, wsi);

	/* external POLL support via protocol 0 */
	if (context->protocols[0].callback(wsi, LWS_CALLBACK_ADD_POLL_FD,
					   wsi->user_space, (void *) &pa, 0))
		return -1;

	if (context->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,
					   wsi->user_space, (void *)&pa, 1))
		return -1;

	return 0;
}
Esempio n. 4
0
struct libwebsocket * __libwebsocket_client_connect_2(
	struct libwebsocket_context *context,
	struct libwebsocket *wsi
) {
	struct pollfd pfd;
	struct timeval tv;
	struct hostent *server_hostent;
	struct sockaddr_in server_addr;
	int n;
	int plen = 0;
	char pkt[512];
	int opt = 1;
#if defined(__APPLE__)
    struct protoent* tcp_proto;
#endif

	lws_log(LWS_LOG_DEBUG, "__libwebsocket_client_connect_2");

	wsi->candidate_children_list = NULL;

	/*
	 * proxy?
	 */

	if (context->http_proxy_port) {
		plen = sprintf(pkt, "CONNECT %s:%u HTTP/1.0\x0d\x0a"
			"User-agent: libwebsockets\x0d\x0a"
/*Proxy-authorization: basic aGVsbG86d29ybGQ= */
			"\x0d\x0a", wsi->c_address, wsi->c_port);

		/* OK from now on we talk via the proxy */

		free(wsi->c_address);
		wsi->c_address = strdup(context->http_proxy_address);
		wsi->c_port = context->http_proxy_port;
	}

	/*
	 * prepare the actual connection (to the proxy, if any)
	 */

	lws_log(LWS_LOG_DEBUG, "__libwebsocket_client_connect_2: address %s", wsi->c_address);

	server_hostent = gethostbyname(wsi->c_address);
	if (server_hostent == NULL) {
		lws_log(LWS_LOG_WARNING, "Unable to get host name from %s",
								wsi->c_address);
		goto oom4;
	}

	wsi->sock = socket(AF_INET, SOCK_STREAM, 0);

	if (wsi->sock < 0) {
		lws_log(LWS_LOG_WARNING, "Unable to open socket");
		goto oom4;
	}

	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(wsi->c_port);
	server_addr.sin_addr = *((struct in_addr *)server_hostent->h_addr);
	bzero(&server_addr.sin_zero, 8);

	/* Disable Nagle */
#if !defined(__APPLE__)
	setsockopt(wsi->sock, SOL_TCP, TCP_NODELAY, (const void *)&opt, sizeof(opt));
#else
    tcp_proto = getprotobyname("TCP");
    setsockopt(wsi->sock, tcp_proto->p_proto, TCP_NODELAY, &opt, sizeof(opt));
#endif

	/* Set receiving timeout */
	tv.tv_sec = 0;
	tv.tv_usec = 100 * 1000;
	setsockopt(wsi->sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv);

	/* Set sendind timeout */
	tv.tv_sec = 0;
	tv.tv_usec = 100 * 1000;
	setsockopt(wsi->sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof tv);

	if (connect(wsi->sock, (struct sockaddr *)&server_addr,
					      sizeof(struct sockaddr)) == -1)  {
		lws_log(LWS_LOG_WARNING, "Connect failed");
#ifdef WIN32
		closesocket(wsi->sock);
#else
		close(wsi->sock);
#endif
		goto oom4;
	}

	lws_log(LWS_LOG_DEBUG, "connected");

	/* into fd -> wsi hashtable */

	insert_wsi(context, wsi);

	/* into internal poll list */

	context->fds[context->fds_count].fd = wsi->sock;
	context->fds[context->fds_count].revents = 0;
	context->fds[context->fds_count++].events = POLLIN;

	/* external POLL support via protocol 0 */
	context->protocols[0].callback(context, wsi,
		LWS_CALLBACK_ADD_POLL_FD,
		(void *)(long)wsi->sock, NULL, POLLIN);

	/* we are connected to server, or proxy */

	if (context->http_proxy_port) {

		n = send(wsi->sock, pkt, plen, 0);
		if (n < 0) {
#ifdef WIN32
			closesocket(wsi->sock);
#else
			close(wsi->sock);
#endif
			lws_log(LWS_LOG_ERROR, "ERROR writing to proxy socket");
			goto bail1;
		}

		libwebsocket_set_timeout(wsi,
			PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, AWAITING_TIMEOUT);

		wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY;

		return wsi;
	}

	/*
	 * provoke service to issue the handshake directly
	 * we need to do it this way because in the proxy case, this is the
	 * next state and executed only if and when we get a good proxy
	 * response inside the state machine
	 */

	wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE;
	pfd.fd = wsi->sock;
	pfd.revents = POLLIN;
	if (libwebsocket_service_fd(context, &pfd)) /* returns 1 on failure after closing wsi */
	{
		return NULL;
	}

	return wsi;

oom4:
	if (wsi->c_protocol)
		free(wsi->c_protocol);

	if (wsi->c_origin)
		free(wsi->c_origin);

	free(wsi->c_host);
	free(wsi->c_path);

bail1:
	free(wsi);

	return NULL;
}