Ejemplo n.º 1
0
void ws_events_send(ws_t *ws, char *str)
{
	log_debug(2, "ws_events_send '%s'", str);

	ws_session_foreach(ws, (hk_tab_foreach_func) ws_events_send_session, str);

	lws_callback_on_writable_all_protocol(ws->server.context, ws_events_protocol);
}
Ejemplo n.º 2
0
bool FJavascriptWebSocketServer::Tick()
{
	if (IsAlive)
	{
		lws_service(Context, 0);
		lws_callback_on_writable_all_protocol(Context, &Protocols[0]);
	}
	return true;
}
static void
uv_timeout_cb_dumb_increment(uv_timer_t *w
#if UV_VERSION_MAJOR == 0
		, int status
#endif
)
{
	lws_callback_on_writable_all_protocol(context,
					&protocols[PROTOCOL_DUMB_INCREMENT]);
}
Ejemplo n.º 4
0
bool FWebSocketServer::Tick()
{
#if !PLATFORM_HTML5
	if (IsAlive)
	{
		lws_service(Context, 0);
		lws_callback_on_writable_all_protocol(Context, &Protocols[0]);
	}
#endif
	return true;
}
static void
update_status(struct lws *wsi, struct per_session_data__lws_status *pss)
{
    struct per_session_data__lws_status **pp = &list;
    int subsequent = 0;
    char *p = cache + LWS_PRE, *start = p;
    char date[128];
    time_t t;
    struct tm *ptm;
#ifndef WIN32
    struct tm tm;
#endif

    p += snprintf(p, 512, " { %s, \"wsi\":\"%d\", \"conns\":[",
                  server_info, live_wsi);

    /* render the list */
    while (*pp) {
        t = (*pp)->tv_established.tv_sec;
#ifdef WIN32
        ptm = localtime(&t);
        if (!ptm)
#else
        ptm = &tm;
        if (!localtime_r(&t, &tm))
#endif
            strcpy(date, "unknown");
        else
            strftime(date, sizeof(date), "%F %H:%M %Z", ptm);
        if ((p - start) > (sizeof(cache) - 512))
            break;
        if (subsequent)
            *p++ = ',';
        subsequent = 1;
        p += snprintf(p, sizeof(cache) - (p - start) - 1,
                      "{\"peer\":\"%s\",\"time\":\"%s\","
                      "\"ua\":\"%s\"}",
                      (*pp)->ip, date, (*pp)->user_agent);
        pp = &((*pp)->list);
    }

    p += sprintf(p, "]}");
    cache_len = p - start;
    lwsl_err("cache_len %d\n", cache_len);
    *p = '\0';

    /* since we changed the list, increment the 'version' */
    current++;
    /* update everyone */
    lws_callback_on_writable_all_protocol(lws_get_context(wsi),
                                          lws_get_protocol(wsi));
}
Ejemplo n.º 6
0
/* Multithreaded server */
void *thread_lws_mirror(void *threadid) {
   while (!force_exit) {
        /*
         * this lock means wsi in the active list cannot
         * disappear underneath us, because the code to add and remove
         * them is protected by the same lock
         */
        pthread_mutex_lock(&lock_established_conns);
        lws_callback_on_writable_all_protocol(context, &protocols[PROTOCOL_LWS_MIRROR]);
        pthread_mutex_unlock(&lock_established_conns);
        usleep(100000);
    }

    pthread_exit(NULL);
}
uint32 FNetworkFileServerHttp::Run()
{
	UE_LOG(LogFileServer, Display, TEXT("Unreal Network File Http Server is ready for client connections on port %d"), Port);

	// start servicing.

	// service libwebsocket context.
	while(!StopRequested.GetValue())
	{
		// service libwebsocket, have a slight delay so it doesn't spin on zero load.
		lws_service(Context, 10);
		lws_callback_on_writable_all_protocol(Context, &Protocols[0]);
	}

	UE_LOG(LogFileServer, Display, TEXT("Unreal Network File Http Server is now Shutting down "));
	return true;
}
Ejemplo n.º 8
0
void FWebSocket::HandlePacket()
{
#if !PLATFORM_HTML5

	lws_service(Context, 0);
	if (!IsServerSide)
		lws_callback_on_writable_all_protocol(Context, &Protocols[0]);

#else // PLATFORM_HTML5

	fd_set Fdr;
	fd_set Fdw;
	int Res;

	// make sure that server.fd is ready to read / write
	FD_ZERO(&Fdr);
	FD_ZERO(&Fdw);
	FD_SET(SockFd, &Fdr);
	FD_SET(SockFd, &Fdw);
	Res = select(64, &Fdr, &Fdw, NULL, NULL);

	if (Res == -1) {
		UE_LOG(LogHTML5Networking, Warning, TEXT("Select Failed!"));
		return;
	}

	if (FD_ISSET(SockFd, &Fdr)) {
		// we can read!
		OnRawRecieve(NULL, NULL);
	}

	if (FD_ISSET(SockFd, &Fdw)) {
		// we can write
		OnRawWebSocketWritable(NULL);
	}

#endif
}
Ejemplo n.º 9
0
void FWebSocket::Flush()
{
	auto PendingMesssages = OutgoingBuffer.Num();
	while (OutgoingBuffer.Num() > 0 && !IsServerSide)
	{
#if !PLATFORM_HTML5
		if (Protocols)
		{
			lws_callback_on_writable_all_protocol(Context, &Protocols[0]);
		}
		else
		{
			lws_callback_on_writable(Wsi);
		}
#endif
		HandlePacket();
		if (PendingMesssages <= OutgoingBuffer.Num()) // FIXME! 
		{
			UE_LOG(LogHTML5Networking, Warning, TEXT("Unable to flush all of OutgoingBuffer in FWebSocket."));
			break;
		}
	};
}
Ejemplo n.º 10
0
static int callback_websocket_universal(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
{
	int n;
	struct per_session_data__universal *pss = (struct per_session_data__universal *)user;
    
	switch (reason) {

	case LWS_CALLBACK_ESTABLISHED:
        printf("transport_mock_websocket_server_t LWS_CALLBACK_ESTABLISHED\n");
		pss->ringbuffer_tail = ringbuffer_head;
		pss->wsi = wsi;
		break;

	case LWS_CALLBACK_PROTOCOL_DESTROY:
       printf("transport_mock_websocket_server_t LWS_CALLBACK_PROTOCOL_DESTROY\n");
		for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++)
			if (ringbuffer[n].payload)
				free(ringbuffer[n].payload);
		break;
	case LWS_CALLBACK_SERVER_WRITEABLE:
        printf("transport_mock_websocket_server_t LWS_CALLBACK_SERVER_WRITEABLE\n");
		while (pss->ringbuffer_tail != ringbuffer_head) {

			n = lws_write(wsi, (unsigned char *)
				   ringbuffer[pss->ringbuffer_tail].payload +
				   LWS_SEND_BUFFER_PRE_PADDING,
				   ringbuffer[pss->ringbuffer_tail].len,
								LWS_WRITE_BINARY);
			if (n < ringbuffer[pss->ringbuffer_tail].len) {
				lwsl_err("ERROR %d writing to mirror socket\n", n);
				return -1;
			}
			if (n < ringbuffer[pss->ringbuffer_tail].len)
				lwsl_err("mirror partial write %d vs %d\n",
				       n, ringbuffer[pss->ringbuffer_tail].len);

			if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1))
				pss->ringbuffer_tail = 0;
			else
				pss->ringbuffer_tail++;

			if (((ringbuffer_head - pss->ringbuffer_tail) &
				  (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
				lws_rx_flow_allow_all_protocol(lws_get_context(wsi), lws_get_protocol(wsi));

			// lwsl_debug("tx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1));

			if (lws_send_pipe_choked(wsi)) {
				lws_callback_on_writable(wsi);
				break;
			}
			/*
			 * for tests with chrome on same machine as client and
			 * server, this is needed to stop chrome choking
			 */
			usleep(1);
		}
		break;

	case LWS_CALLBACK_RECEIVE:
        printf("transport_mock_websocket_server_t LWS_CALLBACK_RECEIVE (%lu)\n", len);
		if (((ringbuffer_head - pss->ringbuffer_tail) &
				  (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) {
			lwsl_err("dropping!\n");
			goto choke;
		}

		if (ringbuffer[ringbuffer_head].payload)
			free(ringbuffer[ringbuffer_head].payload);

		ringbuffer[ringbuffer_head].payload =
				malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
						  LWS_SEND_BUFFER_POST_PADDING);
		ringbuffer[ringbuffer_head].len = len;
		memcpy((char *)ringbuffer[ringbuffer_head].payload +
					  LWS_SEND_BUFFER_PRE_PADDING, in, len);
		if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1))
			ringbuffer_head = 0;
		else
			ringbuffer_head++;

		if (((ringbuffer_head - pss->ringbuffer_tail) &
				  (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2))
			goto done;

choke:
		lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi);
		lws_rx_flow_control(wsi, 0);

//		lwsl_debug("rx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1));
done:
		lws_callback_on_writable_all_protocol(lws_get_context(wsi), lws_get_protocol(wsi));
		break;

	/*
	 * this just demonstrates how to use the protocol filter. If you won't
	 * study and reject connections based on header content, you don't need
	 * to handle this callback
	 */
	case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
        printf("transport_mock_websocket_server_t LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n");
		//dump_handshake_info(wsi);
		/* you could return non-zero here and kill the connection */
		break;

	default:
		break;
	}

	return 0;
}
Ejemplo n.º 11
0
int main(int argc, char **argv)
{
	struct lws_context_creation_info info;
	unsigned int ms, oldms = 0;
	const char *iface = NULL;
	char cert_path[1024];
	char key_path[1024];
	int use_ssl = 0;
	int opts = 0;
	int n = 0;

	/*
	 * take care to zero down the info struct, he contains random garbaage
	 * from the stack otherwise
	 */
	 memset(&info, 0, sizeof info);
	 info.port = 7681;





	 signal(SIGINT, sighandler);



	/* tell the library what debug level to emit and to send it to syslog */
	 lws_set_log_level(debug_level, lwsl_emit_syslog);

	 lwsl_notice("libwebsockets test server - license LGPL2.1+SLE\n");
	 lwsl_notice("(C) Copyright 2010-2016 Andy Green <*****@*****.**>\n");

	 printf("Using resource path \"%s\"\n", resource_path);


	 info.iface = iface;
	 info.protocols = protocols;
	 info.ssl_cert_filepath = NULL;
	 info.ssl_private_key_filepath = NULL;

	 if (use_ssl) {
	 	if (strlen(resource_path) > sizeof(cert_path) - 32) {
	 		lwsl_err("resource path too long\n");
	 		return -1;
	 	}
	 	sprintf(cert_path, "%s/libwebsockets-test-server.pem",
	 		resource_path);
	 	if (strlen(resource_path) > sizeof(key_path) - 32) {
	 		lwsl_err("resource path too long\n");
	 		return -1;
	 	}
	 	sprintf(key_path, "%s/libwebsockets-test-server.key.pem",
	 		resource_path);

	 	info.ssl_cert_filepath = cert_path;
	 	info.ssl_private_key_filepath = key_path;
	 }
	 info.gid = -1;
	 info.uid = -1;
	 info.max_http_header_pool = 1;
	 info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8;
	 info.extensions = NULL;
	 context = lws_create_context(&info);
	 if (context == NULL) {
	 	lwsl_err("libwebsocket init failed\n");
	 	return -1;
	 }

	/* this shows how to override the lws file operations.  You don't need
	 * to do any of this unless you have a reason (eg, want to serve
	 * compressed files without decompressing the whole archive)
	 */
	/* stash original platform fops */
fops_plat = *(lws_get_fops(context));
	/* override the active fops */
lws_get_fops(context)->open = test_server_fops_open;

n = 0;
while (n >= 0 && !force_exit) {
	struct timeval tv;

	gettimeofday(&tv, NULL);

		/*
		 * This provokes the LWS_CALLBACK_SERVER_WRITEABLE for every
		 * live websocket connection using the DUMB_INCREMENT protocol,
		 * as soon as it can take more packets (usually immediately)
		 */

		 ms = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
		 if ((ms - oldms) > 50) {
		 	lws_callback_on_writable_all_protocol(context,
		 		&protocols[PROTOCOL_DUMB_INCREMENT]);
		 	oldms = ms;
		 }


		/*
		 * If libwebsockets sockets are all we care about,
		 * you can use this api which takes care of the poll()
		 * and looping through finding who needed service.
		 *
		 * If no socket needs service, it'll return anyway after
		 * the number of ms in the second argument.
		 */

		 n = lws_service(context, 50);
		}

		lws_context_destroy(context);

		lwsl_notice("libwebsockets-test-server exited cleanly\n");


		return 0;
	}
Ejemplo n.º 12
0
int
callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
		    void *user, void *in, size_t len)
{
	struct per_session_data__lws_mirror *pss =
			(struct per_session_data__lws_mirror *)user;
	int n, m;
int client_sockfd=lws_get_socket_fd(wsi);
	switch (reason) {

	case LWS_CALLBACK_ESTABLISHED:
		lwsl_notice("%s: LWS_CALLBACK_ESTABLISHED\n", __func__);
		pss->ringbuffer_tail = ringbuffer_head;
		pss->wsi = wsi;
		break;

	case LWS_CALLBACK_PROTOCOL_DESTROY:
		lwsl_notice("%s: mirror protocol cleaning up\n", __func__);
		for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++)
			if (ringbuffer[n].payload)
				free(ringbuffer[n].payload);
		break;

	case LWS_CALLBACK_SERVER_WRITEABLE:
		//if (close_testing)
		//	break;

	printf("服务器开始发送数据\n");
	websocket_write_back(wsi, msg,-1);
	// n = lws_write(wsi, (char*)in + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);

		// while (pss->ringbuffer_tail != ringbuffer_head) {
		// 	m = ringbuffer[pss->ringbuffer_tail].len;
		// 	n = lws_write(wsi, (unsigned char *)
		// 		   ringbuffer[pss->ringbuffer_tail].payload +
		// 		   LWS_PRE, m, LWS_WRITE_TEXT);
			
			
		// 	printf("the n is %d, the cilent fd is %d\n",n,client_sockfd);
		// 	if (n < 0) {
		// 		lwsl_err("ERROR %d writing to mirror socket\n", n);
		// 		return -1;
		// 	}
		// 	if (n < m)
		// 		lwsl_err("mirror partial write %d vs %d\n", n, m);

		// 	if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1))
		// 		pss->ringbuffer_tail = 0;
		// 	else
		// 		pss->ringbuffer_tail++;

		// 	// if (((ringbuffer_head - pss->ringbuffer_tail) &
		// 	//     (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
		// 	// 	lws_rx_flow_allow_all_protocol(lws_get_context(wsi),
		// 	// 		       lws_get_protocol(wsi));

		// 	// if (lws_send_pipe_choked(wsi)) {
		// 	// 	lws_callback_on_writable(wsi);
		// 	// 	break;
		// 	// }
		// }
		break;

	case LWS_CALLBACK_RECEIVE:
	client_sockfd=lws_get_socket_fd(wsi);
	lwsl_notice("接收到客户端 %d 的信息=[%s]\n",client_sockfd, (const char*)in);
	memcpy(msg,in,strlen(in));
		if (((ringbuffer_head - pss->ringbuffer_tail) &
		    (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) {
			lwsl_err("dropping!\n");
			goto choke;
		}

		if (ringbuffer[ringbuffer_head].payload)
			free(ringbuffer[ringbuffer_head].payload);

		ringbuffer[ringbuffer_head].payload = malloc(LWS_PRE + len);
		ringbuffer[ringbuffer_head].len = len;
		memcpy((char *)ringbuffer[ringbuffer_head].payload +
		       LWS_PRE, in, len);
		if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1))
			ringbuffer_head = 0;
		else
			ringbuffer_head++;

		if (((ringbuffer_head - pss->ringbuffer_tail) &
		    (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2))
			goto done;

choke:
		lwsl_notice("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi);
		lws_rx_flow_control(wsi, 0);

done:
	
	printf("lws_callback_on_writable_all_protocol, the client fd is %d\n", client_sockfd);
		lws_callback_on_writable_all_protocol(lws_get_context(wsi),
						      lws_get_protocol(wsi));
		break;

	/*
	 * this just demonstrates how to use the protocol filter. If you won't
	 * study and reject connections based on header content, you don't need
	 * to handle this callback
	 */

	case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
		//dump_handshake_info(wsi);
		/* you could return non-zero here and kill the connection */
		break;

	default:
		break;
	}

	return 0;
}
Ejemplo n.º 13
0
static void
uv_timeout_cb_dumb_increment(uv_timer_t *w)
{
	lws_callback_on_writable_all_protocol(context,
					&protocols[PROTOCOL_DUMB_INCREMENT]);
}
Ejemplo n.º 14
0
Archivo: server.c Proyecto: 5ouya/raspC
int main(int argc, char **argv)
{
	daemonize();
	




	//saveData("admin",100,100,"admin");

	config_obj=parseConfigFile();
	ipWhitelist = cJSON_GetObjectItem(config_obj,"ipWhitelist");

	wiringPiSetup();
	pinDirections = cJSON_GetObjectItem(config_obj,"pinDirections");
	handlePinsDirection(pinDirections);

	signal(SIGINT, sighandler);
	


	struct lws_context_creation_info info;
	unsigned int ms, oldms= 0;
	const char *iface = NULL;
	char cert_path[1024];
	char key_path[1024];
	int use_ssl = 0;
	int opts = 0;
	int n = 0;

	/*
	 * take care to zero down the info struct, he contains random garbaage
	 * from the stack otherwise
	 */
	 memset(&info, 0, sizeof info);
	 info.port = 7681;


	 signal(SIGINT, sighandler);



	 info.iface = iface;
	 info.protocols = protocols;
	 info.ssl_cert_filepath = NULL;
	 info.ssl_private_key_filepath = NULL;

	 if (use_ssl) {
	 	if (strlen(resource_path) > sizeof(cert_path) - 32) {
	 		lwsl_err("resource path too long\n");
	 		return -1;
	 	}
	 	sprintf(cert_path, "%s/libwebsockets-test-server.pem",
	 		resource_path);
	 	if (strlen(resource_path) > sizeof(key_path) - 32) {
	 		lwsl_err("resource path too long\n");
	 		return -1;
	 	}
	 	sprintf(key_path, "%s/libwebsockets-test-server.key.pem",
	 		resource_path);

	 	info.ssl_cert_filepath = cert_path;
	 	info.ssl_private_key_filepath = key_path;
	 }
	 info.gid = -1;
	 info.uid = -1;
	 info.max_http_header_pool = 1;
	 info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8;
	 info.extensions = NULL;
	 context = lws_create_context(&info);
	 if (context == NULL) {
	 	lwsl_err("libwebsocket init failed\n");
	 	return -1;
	 }



	 n = 0;

	 while (n >= 0 && !force_exit) {
	 	struct timeval tv;

	 	gettimeofday(&tv, NULL);

		/*
		 * This provokes the LWS_CALLBACK_SERVER_WRITEABLE for every
		 * live websocket connection using the DUMB_INCREMENT protocol,
		 * as soon as it can take more packets (usually immediately)
		 */
		 extern struct ram_usage ram_l;
		 extern struct cpu_live cpu_l;
		 extern struct cpu_freq cpu_freq;




		if(old_client_count!=client_count){
			if(hash){
				free(hash);
			}

			hash=rand_string();
		 	lws_callback_on_writable_all_protocol(context,
		 		&protocols[PROTOCOL_GPIO]);
		 	lws_callback_on_writable_all_protocol(context,
		 		&protocols[PROTOCOL_DETAILS]);		
		 	lws_callback_on_writable_all_protocol(context,
		 		&protocols[PROTOCOL_SERVICES]);	
		 	lws_callback_on_writable_all_protocol(context,
		 		&protocols[PROTOCOL_HOME]);			 				 			 					
			old_client_count=client_count;
		}

		 ms = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
		 if ((ms - oldms) > 200 && get_client_count()>0 && (cpuLive(&cpu_l,5)==0 && ramLive(&ram_l,5)==0  && cpuLiveFreq(&cpu_freq)==0 )) {
		 	lws_callback_on_writable_all_protocol(context,
		 		&protocols[PROTOCOL_DETAILS]);
		 	oldms = ms;
		 }				 


		 n = lws_service(context, 50);
	}

		lws_context_destroy(context);

		lwsl_notice("libwebsockets-test-server exited cleanly\n");


		return 0;
	}
int
callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
			void *user, void *in, size_t len)
{
	struct per_session_data__lws_mirror *pss =
			(struct per_session_data__lws_mirror *)user;
	int m,n;

	switch (reason) {

	case LWS_CALLBACK_ESTABLISHED:
		lwsl_info("callback_lws_mirror: LWS_CALLBACK_ESTABLISHED\n", __func__);
		pss->ringbuffer_tail = ringbuffer_head;
		pss->wsi = wsi;
		break;

	case LWS_CALLBACK_PROTOCOL_DESTROY:
		lwsl_notice("mirror protocol cleaning up\n");
		for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++)
			if (ringbuffer[n].payload)
				free(ringbuffer[n].payload);
		break;

	case LWS_CALLBACK_SERVER_WRITEABLE:
		if (close_testing)
			break;
		while (pss->ringbuffer_tail != ringbuffer_head) {
			m = ringbuffer[pss->ringbuffer_tail].len;
			n = lws_write(wsi, (unsigned char *)
					ringbuffer[pss->ringbuffer_tail].payload +
					LWS_PRE, m, LWS_WRITE_TEXT);
			if (n < 0) {
				lwsl_err("ERROR %d writing to mirror socket\n", n);
				return -1;
			}
			if (n < m)
				lwsl_err("mirror partial write %d vs %d\n", n, m);

			if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1))
				pss->ringbuffer_tail = 0;
			else
				pss->ringbuffer_tail++;

			if (((ringbuffer_head - pss->ringbuffer_tail) &
				  (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
				lws_rx_flow_allow_all_protocol(lws_get_context(wsi),
						lws_get_protocol(wsi));

			if (lws_send_pipe_choked(wsi)) {
				lws_callback_on_writable(wsi);
				break;
			}
			/*
			 * for tests with chrome on same machine as client and
			 * server, this is needed to stop chrome choking
			 */
			usleep(1);
		}
		break;

	case LWS_CALLBACK_RECEIVE:

		if (((ringbuffer_head - pss->ringbuffer_tail) &
				  (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) {
			lwsl_err("dropping!\n");
			goto choke;
		}

		if (ringbuffer[ringbuffer_head].payload)
			free(ringbuffer[ringbuffer_head].payload);

		ringbuffer[ringbuffer_head].payload =
				malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
						  LWS_SEND_BUFFER_POST_PADDING);
		ringbuffer[ringbuffer_head].len = len;
		memcpy((char *)ringbuffer[ringbuffer_head].payload +
					  LWS_SEND_BUFFER_PRE_PADDING, in, len);
		if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1))
			ringbuffer_head = 0;
		else
			ringbuffer_head++;

		if (((ringbuffer_head - pss->ringbuffer_tail) &
				  (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2))
			goto done;

choke:
		lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi);
		lws_rx_flow_control(wsi, 0);

done:
		lws_callback_on_writable_all_protocol(lws_get_context(wsi),
						lws_get_protocol(wsi));

		const char *ubus_socket = NULL;
		struct ubus_context *ctx;
		static struct blob_buf b;
		ctx = ubus_connect(ubus_socket);
		if (!ctx) {
			fprintf(stderr, "Failed to connect to ubus\n");
			return -1;
		}		
		blob_buf_init(&b, 0);
		blobmsg_add_json_from_string(&b, (char *)in);
		ubus_send_event(ctx, ubusxevent, b.head);
		ubus_free(ctx);

		break;
	/*
	 * this just demonstrates how to use the protocol filter. If you won't
	 * study and reject connections based on header content, you don't need
	 * to handle this callback
	 */

	case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
		dump_handshake_info(wsi);
		/* you could return non-zero here and kill the connection */
		break;

	default:
		break;
	}

	return 0;
}
Ejemplo n.º 16
0
int
callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
		    void *user, void *in, size_t len)
{
	struct per_session_data__lws_mirror *pss =
			(struct per_session_data__lws_mirror *)user;
	int n;

	switch (reason) {

	case LWS_CALLBACK_ESTABLISHED:
		lwsl_info("%s: LWS_CALLBACK_ESTABLISHED\n", __func__);
		pss->ringbuffer_tail = ringbuffer_head;
		pss->wsi = wsi;
		break;

	case LWS_CALLBACK_PROTOCOL_DESTROY:
		lwsl_notice("%s: mirror protocol cleaning up\n", __func__);
		for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++)
			if (ringbuffer[n].payload)
				free(ringbuffer[n].payload);
		break;

	case LWS_CALLBACK_SERVER_WRITEABLE:
		if (close_testing)
			break;
		while (pss->ringbuffer_tail != ringbuffer_head) {

			n = lws_write(wsi, (unsigned char *)
				   ringbuffer[pss->ringbuffer_tail].payload +
				   LWS_SEND_BUFFER_PRE_PADDING,
				   ringbuffer[pss->ringbuffer_tail].len,
								LWS_WRITE_TEXT);
			if (n < 0) {
				lwsl_err("ERROR %d writing to mirror socket\n", n);
				return -1;
			}
			if (n < (int)ringbuffer[pss->ringbuffer_tail].len)
				lwsl_err("mirror partial write %d vs %d\n",
				       n, ringbuffer[pss->ringbuffer_tail].len);

			if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1))
				pss->ringbuffer_tail = 0;
			else
				pss->ringbuffer_tail++;

			if (((ringbuffer_head - pss->ringbuffer_tail) &
			    (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
				lws_rx_flow_allow_all_protocol(lws_get_context(wsi),
					       lws_get_protocol(wsi));

			if (lws_partial_buffered(wsi) ||
			    lws_send_pipe_choked(wsi)) {
				lws_callback_on_writable(wsi);
				break;
			}
		}
		break;

	case LWS_CALLBACK_RECEIVE:
		if (((ringbuffer_head - pss->ringbuffer_tail) &
		    (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) {
			lwsl_err("dropping!\n");
			goto choke;
		}

		if (ringbuffer[ringbuffer_head].payload)
			free(ringbuffer[ringbuffer_head].payload);

		ringbuffer[ringbuffer_head].payload =
				malloc(LWS_SEND_BUFFER_PRE_PADDING + len);
		ringbuffer[ringbuffer_head].len = len;
		memcpy((char *)ringbuffer[ringbuffer_head].payload +
					  LWS_SEND_BUFFER_PRE_PADDING, in, len);
		if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1))
			ringbuffer_head = 0;
		else
			ringbuffer_head++;

		if (((ringbuffer_head - pss->ringbuffer_tail) &
		    (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2))
			goto done;

choke:
		lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi);
		lws_rx_flow_control(wsi, 0);

done:
		lws_callback_on_writable_all_protocol(lws_get_context(wsi),
						      lws_get_protocol(wsi));
		break;

	/*
	 * this just demonstrates how to use the protocol filter. If you won't
	 * study and reject connections based on header content, you don't need
	 * to handle this callback
	 */

	case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
		dump_handshake_info(wsi);
		/* you could return non-zero here and kill the connection */
		break;

	default:
		break;
	}

	return 0;
}
Ejemplo n.º 17
0
int main(int argc, char **argv)
{
	char cert_path[1024];
	char key_path[1024];
	int n = 0;
	int use_ssl = 0;
	int opts = 0;
	char interface_name[128] = "";
	const char *iface = NULL;
	int syslog_options = LOG_PID | LOG_PERROR;
	struct lws_context_creation_info info;

	int debug_level = 7;
#ifndef LWS_NO_DAEMONIZE
	int daemonize = 0;
#endif

	memset(&info, 0, sizeof info);
	info.port = 7681;

	while (n >= 0) {
		n = getopt_long(argc, argv, "eci:hsap:d:Dr:", options, NULL);
		if (n < 0)
			continue;
		switch (n) {
#ifndef LWS_NO_DAEMONIZE
		case 'D':
			daemonize = 1;
			syslog_options &= ~LOG_PERROR;
			break;
#endif
		case 'd':
			debug_level = atoi(optarg);
			break;
		case 's':
			use_ssl = 1;
			break;
		case 'p':
			info.port = atoi(optarg);
			break;
		case 'i':
			strncpy(interface_name, optarg, sizeof interface_name);
			interface_name[(sizeof interface_name) - 1] = '\0';
			iface = interface_name;
			break;
		case 'c':
			close_testing = 1;
			fprintf(stderr, " Close testing mode -- closes on "
			                "client after 50 messages.\n");
			break;
		case 'r':
			resource_path = optarg;
			printf("Setting resource path to \"%s\"\n",
			       resource_path);
			break;
		case 'h':
			fprintf(stderr,
			        "Usage: " PROGNAME "[--port=<p>] [--ssl] "
			        "[-d <log bitfield>] "
			        "[--resource_path <path>]\n");
			exit(1);
		}
	}

#if !defined(LWS_NO_DAEMONIZE)
	/*
	 * normally lock path would be /var/lock/lwsts or similar, to
	 * simplify getting started without having to take care about
	 * permissions or running as root, set to /tmp/.lwsts-lock
	 */
	if (daemonize && lws_daemonize("/tmp/.lwsts-lock")) {
		fprintf(stderr, "Failed to daemonize\n");
		return 1;
	}
#endif

	signal(SIGINT, sighandler);

	/* we will only try to log things according to our debug_level */
	setlogmask(LOG_UPTO(LOG_DEBUG));
	openlog("lwsts", syslog_options, LOG_DAEMON);

	/* tell the library what debug level to emit and to send it to syslog */
	lws_set_log_level(debug_level, lwsl_emit_syslog);

	lwsl_notice("jittertrap server\n");

	printf("Using resource path \"%s\"\n", resource_path);

	info.iface = iface;
	info.protocols = protocols;
#ifndef LWS_NO_EXTENSIONS
	info.extensions = lws_get_internal_extensions();
#endif
	if (!use_ssl) {
		info.ssl_cert_filepath = NULL;
		info.ssl_private_key_filepath = NULL;
	} else {
		if (strlen(resource_path) > sizeof(cert_path) - 32) {
			lwsl_err("resource path too long\n");
			return -1;
		}
		sprintf(cert_path, "%s/libwebsockets-test-server.pem",
		        resource_path);

		if (strlen(resource_path) > sizeof(key_path) - 32) {
			lwsl_err("resource path too long\n");
			return -1;
		}
		sprintf(key_path, "%s/libwebsockets-test-server.key.pem",
		        resource_path);

		info.ssl_cert_filepath = cert_path;
		info.ssl_private_key_filepath = key_path;
	}
	info.gid = -1;
	info.uid = -1;
	info.options = opts;

	context = lws_create_context(&info);
	if (context == NULL) {
		lwsl_err("libwebsocket init failed\n");
		return -1;
	}

	n = 0;
	while (n >= 0 && !force_exit) {
		lws_callback_on_writable_all_protocol(
		    context, &protocols[PROTOCOL_JITTERTRAP]);

		/* FIXME: something is causing us to spin. This helps to
		 * slow things down, but it's not a proper solution.
		 */
		usleep(1);

		/*
		 * takes care of the poll() and looping through finding who
		 * needs service.
		 *
		 * If no socket needs service, it'll return anyway after
		 * the number of ms in the second argument.
		 */

		n = lws_service(context, 1);
	}

	lws_context_destroy(context);

	lwsl_notice("jittertrap server exited cleanly\n");

	closelog();

	return 0;
}
Ejemplo n.º 18
0
static void
ev_timeout_cb (EV_P_ ev_timer *w, int revents)
{
	lws_callback_on_writable_all_protocol(context,
					&protocols[PROTOCOL_DUMB_INCREMENT]);
}
Ejemplo n.º 19
0
void transport_mock_websocket_server_run(transport_mock_websocket_server_t transport_mock_websocket_server)
{
	lws_callback_on_writable_all_protocol(transport_mock_websocket_server->ws_context, &protocols[0]);
    lws_service(transport_mock_websocket_server->ws_context, 50);
}
Ejemplo n.º 20
0
int main(int argc, char **argv)
{
	struct lws_context_creation_info info;
	struct lws_vhost *vhost;
	char interface_name[128] = "";
	unsigned int ms, oldms = 0;
	const char *iface = NULL;
	char cert_path[1024] = "";
	char key_path[1024] = "";
	char ca_path[1024] = "";
	int uid = -1, gid = -1;
	int use_ssl = 0;
	int pp_secs = 0;
	int opts = 0;
	int n = 0;
#ifndef _WIN32
/* LOG_PERROR is not POSIX standard, and may not be portable */
#ifdef __sun
	int syslog_options = LOG_PID;
#else
	int syslog_options = LOG_PID | LOG_PERROR;
#endif
#endif
#ifndef LWS_NO_DAEMONIZE
	int daemonize = 0;
#endif

	/*
	 * take care to zero down the info struct, he contains random garbaage
	 * from the stack otherwise
	 */
	memset(&info, 0, sizeof info);
	info.port = 7681;

	while (n >= 0) {
		n = getopt_long(argc, argv, "eci:hsap:d:Dr:C:K:A:R:vu:g:P:k",
				options, NULL);
		if (n < 0)
			continue;
		switch (n) {
		case 'e':
			opts |= LWS_SERVER_OPTION_LIBEV;
			break;
#ifndef LWS_NO_DAEMONIZE
		case 'D':
			daemonize = 1;
#if !defined(_WIN32) && !defined(__sun)
			syslog_options &= ~LOG_PERROR;
#endif
			break;
#endif
		case 'u':
			uid = atoi(optarg);
			break;
		case 'g':
			gid = atoi(optarg);
			break;
		case 'd':
			debug_level = atoi(optarg);
			break;
		case 's':
			use_ssl = 1;
			break;
		case 'a':
			opts |= LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT;
			break;
		case 'p':
			info.port = atoi(optarg);
			break;
		case 'i':
			strncpy(interface_name, optarg, sizeof interface_name);
			interface_name[(sizeof interface_name) - 1] = '\0';
			iface = interface_name;
			break;
		case 'k':
			info.bind_iface = 1;
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
			info.caps[0] = CAP_NET_RAW;
			info.count_caps = 1;
#endif
			break;
		case 'c':
			close_testing = 1;
			fprintf(stderr, " Close testing mode -- closes on "
				"client after 50 dumb increments"
				"and suppresses lws_mirror spam\n");
			break;
		case 'r':
			resource_path = optarg;
			printf("Setting resource path to \"%s\"\n",
			       resource_path);
			break;
		case 'C':
			strncpy(cert_path, optarg, sizeof(cert_path) - 1);
			cert_path[sizeof(cert_path) - 1] = '\0';
			break;
		case 'K':
			strncpy(key_path, optarg, sizeof(key_path) - 1);
			key_path[sizeof(key_path) - 1] = '\0';
			break;
		case 'A':
			strncpy(ca_path, optarg, sizeof(ca_path) - 1);
			ca_path[sizeof(ca_path) - 1] = '\0';
			break;
		case 'P':
			pp_secs = atoi(optarg);
			lwsl_notice("Setting pingpong interval to %d\n",
				    pp_secs);
			break;
#if defined(LWS_OPENSSL_SUPPORT)
		case 'v':
			use_ssl = 1;
			opts |=
			    LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;
			break;

#if defined(LWS_HAVE_SSL_CTX_set1_param)
		case 'R':
			strncpy(crl_path, optarg, sizeof(crl_path) - 1);
			crl_path[sizeof(crl_path) - 1] = '\0';
			break;
#endif
#endif
		case 'h':
			fprintf(stderr, "Usage: test-server "
				"[--port=<p>] [--ssl] "
				"[-d <log bitfield>] "
				"[--resource_path <path>]\n");
			exit(1);
		}
	}

#if !defined(LWS_NO_DAEMONIZE) && !defined(WIN32)
	/*
	 * normally lock path would be /var/lock/lwsts or similar, to
	 * simplify getting started without having to take care about
	 * permissions or running as root, set to /tmp/.lwsts-lock
	 */
	if (daemonize && lws_daemonize("/tmp/.lwsts-lock")) {
		fprintf(stderr, "Failed to daemonize\n");
		return 10;
	}
#endif

	signal(SIGINT, sighandler);

#ifndef _WIN32
	/* we will only try to log things according to our debug_level */
	setlogmask(LOG_UPTO(LOG_DEBUG));
	openlog("lwsts", syslog_options, LOG_DAEMON);
#endif

	/* tell the library what debug level to emit and to send it to syslog */
	lws_set_log_level(debug_level, lwsl_emit_syslog);

	lwsl_notice("libwebsockets test server - license LGPL2.1+SLE\n");
	lwsl_notice("(C) Copyright 2010-2016 Andy Green <*****@*****.**>\n");

	printf("Using resource path \"%s\"\n", resource_path);
#ifdef EXTERNAL_POLL
	max_poll_elements = getdtablesize();
	pollfds = malloc(max_poll_elements * sizeof(struct lws_pollfd));
	fd_lookup = malloc(max_poll_elements * sizeof(int));
	if (pollfds == NULL || fd_lookup == NULL) {
		lwsl_err("Out of memory pollfds=%d\n", max_poll_elements);
		return -1;
	}
#endif

	info.iface = iface;
	info.protocols = protocols;
	info.ssl_cert_filepath = NULL;
	info.ssl_private_key_filepath = NULL;
	info.ws_ping_pong_interval = pp_secs;

	if (use_ssl) {
		if (strlen(resource_path) > sizeof(cert_path) - 32) {
			lwsl_err("resource path too long\n");
			return -1;
		}
		if (!cert_path[0])
			sprintf(cert_path, "%s/libwebsockets-test-server.pem",
				resource_path);
		if (strlen(resource_path) > sizeof(key_path) - 32) {
			lwsl_err("resource path too long\n");
			return -1;
		}
		if (!key_path[0])
			sprintf(key_path,
				"%s/libwebsockets-test-server.key.pem",
				resource_path);

		info.ssl_cert_filepath = cert_path;
		info.ssl_private_key_filepath = key_path;
		if (ca_path[0])
			info.ssl_ca_filepath = ca_path;
	}
	info.gid = gid;
	info.uid = uid;
	info.max_http_header_pool = 16;
	info.options =
	    opts | LWS_SERVER_OPTION_VALIDATE_UTF8 |
	    LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
	    LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
	info.extensions = exts;
	info.timeout_secs = 5;
	info.ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
	    "ECDHE-RSA-AES256-GCM-SHA384:"
	    "DHE-RSA-AES256-GCM-SHA384:"
	    "ECDHE-RSA-AES256-SHA384:"
	    "HIGH:!aNULL:!eNULL:!EXPORT:"
	    "!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:"
	    "!SHA1:!DHE-RSA-AES128-GCM-SHA256:"
	    "!DHE-RSA-AES128-SHA256:"
	    "!AES128-GCM-SHA256:"
	    "!AES128-SHA256:"
	    "!DHE-RSA-AES256-SHA256:" "!AES256-GCM-SHA384:" "!AES256-SHA256";

	if (use_ssl)
		/* redirect guys coming on http */
		info.options |= LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS;

	printf("options:%x\r\n", info.options);
	printf("before create\n");
	context = lws_create_context(&info);
	printf("end create\n");
	if (context == NULL) {
		lwsl_err("libwebsocket init failed\n");
		return -1;
	}

	printf("111111\r\n");
	vhost = lws_create_vhost(context, &info);
	if (!vhost) {
		lwsl_err("vhost creation failed\n");
		return -1;
	}
	printf("222222\r\n");
#if !defined(LWS_NO_CLIENT) && defined(LWS_OPENSSL_SUPPORT)
	lws_init_vhost_client_ssl(&info, vhost);
#endif

	/* this shows how to override the lws file operations.  You don't need
	 * to do any of this unless you have a reason (eg, want to serve
	 * compressed files without decompressing the whole archive)
	 */
	/* stash original platform fops */
	fops_plat = *(lws_get_fops(context));
	/* override the active fops */
	lws_get_fops(context)->open = test_server_fops_open;

	n = 0;
#ifdef EXTERNAL_POLL
	int ms_1sec = 0;
#endif
	while (n >= 0 && !force_exit) {
		struct timeval tv;

		gettimeofday(&tv, NULL);

		/*
		 * This provokes the LWS_CALLBACK_SERVER_WRITEABLE for every
		 * live websocket connection using the DUMB_INCREMENT protocol,
		 * as soon as it can take more packets (usually immediately)
		 */

		ms = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
		if ((ms - oldms) > 1) {
			lws_callback_on_writable_all_protocol(context,
							      &protocols
							      [PROTOCOL_DUMB_INCREMENT]);
			oldms = ms;

		}

		lws_callback_on_writable_all_protocol(context,
						      &protocols
						      [PROTOCOL_FILE_SERVER_SEND]);

#ifdef EXTERNAL_POLL
		/*
		 * this represents an existing server's single poll action
		 * which also includes libwebsocket sockets
		 */

		n = poll(pollfds, count_pollfds, 50);
		if (n < 0)
			continue;

		if (n) {
			for (n = 0; n < count_pollfds; n++)
				if (pollfds[n].revents)
					/*
					 * returns immediately if the fd does not
					 * match anything under libwebsockets
					 * control
					 */
					if (lws_service_fd(context,
							   &pollfds[n]) < 0)
						goto done;

			/* if needed, force-service wsis that may not have read all input */
			while (!lws_service_adjust_timeout(context, 1, 0)) {
				lwsl_notice("extpoll doing forced service!\n");
				lws_service_tsi(context, -1, 0);
			}
		} else {
			/* no revents, but before polling again, make lws check for any timeouts */
			if (ms - ms_1sec > 1000) {
				lwsl_notice("1 per sec\n");
				lws_service_fd(context, NULL);
				ms_1sec = ms;
			}
		}
#else
		/*
		 * If libwebsockets sockets are all we care about,
		 * you can use this api which takes care of the poll()
		 * and looping through finding who needed service.
		 *
		 * If no socket needs service, it'll return anyway after
		 * the number of ms in the second argument.
		 */

		n = lws_service(context, 5);
#endif
	}

#ifdef EXTERNAL_POLL
 done:
#endif

	lws_context_destroy(context);

	lwsl_notice("libwebsockets-test-server exited cleanly\n");

#ifndef _WIN32
	closelog();
#endif

	return 0;
}
Ejemplo n.º 21
0
int main(int argc, char **argv)
{
	struct lws_context_creation_info info;
	char interface_name[128] = "";
	unsigned int ms, oldms = 0;
	const char *iface = NULL;
	char cert_path[1024];
	char key_path[1024];
 	int debug_level = 7;
	int use_ssl = 0;
	int opts = 0;
	int n = 0;
#ifndef _WIN32
	int syslog_options = LOG_PID | LOG_PERROR;
#endif
#ifndef LWS_NO_DAEMONIZE
 	int daemonize = 0;
#endif

	/*
	 * take care to zero down the info struct, he contains random garbaage
	 * from the stack otherwise
	 */
	memset(&info, 0, sizeof info);
	info.port = 7681;

	while (n >= 0) {
		n = getopt_long(argc, argv, "eci:hsap:d:Dr:", options, NULL);
		if (n < 0)
			continue;
		switch (n) {
		case 'e':
			opts |= LWS_SERVER_OPTION_LIBEV;
			break;
#ifndef LWS_NO_DAEMONIZE
		case 'D':
			daemonize = 1;
			#ifndef _WIN32
			syslog_options &= ~LOG_PERROR;
			#endif
			break;
#endif
		case 'd':
			debug_level = atoi(optarg);
			break;
		case 's':
			use_ssl = 1;
			break;
		case 'a':
			opts |= LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT;
			break;
		case 'p':
			info.port = atoi(optarg);
			break;
		case 'i':
			strncpy(interface_name, optarg, sizeof interface_name);
			interface_name[(sizeof interface_name) - 1] = '\0';
			iface = interface_name;
			break;
		case 'c':
			close_testing = 1;
			fprintf(stderr, " Close testing mode -- closes on "
					   "client after 50 dumb increments"
					   "and suppresses lws_mirror spam\n");
			break;
		case 'r':
			resource_path = optarg;
			printf("Setting resource path to \"%s\"\n", resource_path);
			break;
		case 'h':
			fprintf(stderr, "Usage: test-server "
					"[--port=<p>] [--ssl] "
					"[-d <log bitfield>] "
					"[--resource_path <path>]\n");
			exit(1);
		}
	}

#if !defined(LWS_NO_DAEMONIZE) && !defined(WIN32)
	/*
	 * normally lock path would be /var/lock/lwsts or similar, to
	 * simplify getting started without having to take care about
	 * permissions or running as root, set to /tmp/.lwsts-lock
	 */
	if (daemonize && lws_daemonize("/tmp/.lwsts-lock")) {
		fprintf(stderr, "Failed to daemonize\n");
		return 1;
	}
#endif

	signal(SIGINT, sighandler);

#ifndef _WIN32
	/* we will only try to log things according to our debug_level */
	setlogmask(LOG_UPTO (LOG_DEBUG));
	openlog("lwsts", syslog_options, LOG_DAEMON);
#endif

	/* tell the library what debug level to emit and to send it to syslog */
	lws_set_log_level(debug_level, lwsl_emit_syslog);

	lwsl_notice("libwebsockets test server - "
			"(C) Copyright 2010-2015 Andy Green <*****@*****.**> - "
						    "licensed under LGPL2.1\n");

	printf("Using resource path \"%s\"\n", resource_path);
#ifdef EXTERNAL_POLL
	max_poll_elements = getdtablesize();
	pollfds = malloc(max_poll_elements * sizeof (struct lws_pollfd));
	fd_lookup = malloc(max_poll_elements * sizeof (int));
	if (pollfds == NULL || fd_lookup == NULL) {
		lwsl_err("Out of memory pollfds=%d\n", max_poll_elements);
		return -1;
	}
#endif

	info.iface = iface;
	info.protocols = protocols;
#ifndef LWS_NO_EXTENSIONS
	info.extensions = lws_get_internal_extensions();
#endif

	info.ssl_cert_filepath = NULL;
	info.ssl_private_key_filepath = NULL;

	if (use_ssl) {
		if (strlen(resource_path) > sizeof(cert_path) - 32) {
			lwsl_err("resource path too long\n");
			return -1;
		}
		sprintf(cert_path, "%s/libwebsockets-test-server.pem",
								resource_path);
		if (strlen(resource_path) > sizeof(key_path) - 32) {
			lwsl_err("resource path too long\n");
			return -1;
		}
		sprintf(key_path, "%s/libwebsockets-test-server.key.pem",
								resource_path);

		info.ssl_cert_filepath = cert_path;
		info.ssl_private_key_filepath = key_path;
	}
	info.gid = -1;
	info.uid = -1;
	info.max_http_header_pool = 1;
	info.options = opts;

	context = lws_create_context(&info);
	if (context == NULL) {
		lwsl_err("libwebsocket init failed\n");
		return -1;
	}

	/* this shows how to override the lws file operations.  You don't need
	 * to do any of this unless you have a reason (eg, want to serve
	 * compressed files without decompressing the whole archive)
	 */
	/* stash original platform fops */
	fops_plat = *(lws_get_fops(context));
	/* override the active fops */
	lws_get_fops(context)->open = test_server_fops_open;

	n = 0;
	while (n >= 0 && !force_exit) {
		struct timeval tv;

		gettimeofday(&tv, NULL);

		/*
		 * This provokes the LWS_CALLBACK_SERVER_WRITEABLE for every
		 * live websocket connection using the DUMB_INCREMENT protocol,
		 * as soon as it can take more packets (usually immediately)
		 */

		ms = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
		if ((ms - oldms) > 50) {
			lws_callback_on_writable_all_protocol(context,
				&protocols[PROTOCOL_DUMB_INCREMENT]);
			oldms = ms;
		}

#ifdef EXTERNAL_POLL
		/*
		 * this represents an existing server's single poll action
		 * which also includes libwebsocket sockets
		 */

		n = poll(pollfds, count_pollfds, 50);
		if (n < 0)
			continue;

		if (n)
			for (n = 0; n < count_pollfds; n++)
				if (pollfds[n].revents)
					/*
					* returns immediately if the fd does not
					* match anything under libwebsockets
					* control
					*/
					if (lws_service_fd(context,
								  &pollfds[n]) < 0)
						goto done;
#else
		/*
		 * If libwebsockets sockets are all we care about,
		 * you can use this api which takes care of the poll()
		 * and looping through finding who needed service.
		 *
		 * If no socket needs service, it'll return anyway after
		 * the number of ms in the second argument.
		 */

		n = lws_service(context, 50);
#endif
	}

#ifdef EXTERNAL_POLL
done:
#endif

	lws_context_destroy(context);

	lwsl_notice("libwebsockets-test-server exited cleanly\n");

#ifndef _WIN32
	closelog();
#endif

	return 0;
}
Ejemplo n.º 22
0
static int
callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
		    void *user, void *in, size_t len)
{
	struct per_session_data__lws_mirror *pss =
			(struct per_session_data__lws_mirror *)user;
	struct per_vhost_data__lws_mirror *v =
			(struct per_vhost_data__lws_mirror *)
			lws_protocol_vh_priv_get(lws_get_vhost(wsi),
					lws_get_protocol(wsi));
	int n, m;

	switch (reason) {

	case LWS_CALLBACK_ESTABLISHED:
		lwsl_info("%s: LWS_CALLBACK_ESTABLISHED\n", __func__);
		pss->ringbuffer_tail = v->ringbuffer_head;
		pss->wsi = wsi;
		break;

	case LWS_CALLBACK_PROTOCOL_INIT: /* per vhost */
		lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
				lws_get_protocol(wsi),
				sizeof(struct per_vhost_data__lws_mirror));
		break;

	case LWS_CALLBACK_PROTOCOL_DESTROY: /* per vhost */
		if (!v)
			break;
		lwsl_info("%s: mirror protocol cleaning up %p\n", __func__, v);
		for (n = 0; n < ARRAY_SIZE(v->ringbuffer); n++)
			if (v->ringbuffer[n].payload) {
				free(v->ringbuffer[n].payload);
				v->ringbuffer[n].payload = NULL;
			}
		break;

	case LWS_CALLBACK_SERVER_WRITEABLE:
		while (pss->ringbuffer_tail != v->ringbuffer_head) {
			m = v->ringbuffer[pss->ringbuffer_tail].len;
			n = lws_write(wsi, (unsigned char *)
				   v->ringbuffer[pss->ringbuffer_tail].payload +
				   LWS_PRE, m, LWS_WRITE_TEXT);
			if (n < 0) {
				lwsl_err("ERROR %d writing to mirror socket\n", n);
				return -1;
			}
			if (n < m)
				lwsl_err("mirror partial write %d vs %d\n", n, m);

			if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1))
				pss->ringbuffer_tail = 0;
			else
				pss->ringbuffer_tail++;

			if (((v->ringbuffer_head - pss->ringbuffer_tail) &
			    (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
				lws_rx_flow_allow_all_protocol(lws_get_context(wsi),
					       lws_get_protocol(wsi));

			if (lws_send_pipe_choked(wsi)) {
				lws_callback_on_writable(wsi);
				break;
			}
		}
		break;

	case LWS_CALLBACK_RECEIVE:
		if (((v->ringbuffer_head - pss->ringbuffer_tail) &
		    (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) {
			lwsl_err("dropping!\n");
			goto choke;
		}

		if (v->ringbuffer[v->ringbuffer_head].payload)
			free(v->ringbuffer[v->ringbuffer_head].payload);

		v->ringbuffer[v->ringbuffer_head].payload = malloc(LWS_PRE + len);
		v->ringbuffer[v->ringbuffer_head].len = len;
		memcpy((char *)v->ringbuffer[v->ringbuffer_head].payload +
		       LWS_PRE, in, len);
		if (v->ringbuffer_head == (MAX_MESSAGE_QUEUE - 1))
			v->ringbuffer_head = 0;
		else
			v->ringbuffer_head++;

		if (((v->ringbuffer_head - pss->ringbuffer_tail) &
		    (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2))
			goto done;

choke:
		lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi);
		lws_rx_flow_control(wsi, 0);

done:
		lws_callback_on_writable_all_protocol(lws_get_context(wsi),
						      lws_get_protocol(wsi));
		break;

	default:
		break;
	}

	return 0;
}
Ejemplo n.º 23
0
LWS_VISIBLE LWS_EXTERN int
libwebsocket_callback_on_writable_all_protocol(
                 const struct lws_protocols *protocol)
{
    return lws_callback_on_writable_all_protocol(protocol);
}