示例#1
0
static int wslay_event_context_init
(wslay_event_context_ptr *ctx,
 const struct wslay_event_callbacks *callbacks,
 void *user_data)
{
  int i, r;
  struct wslay_frame_callbacks frame_callbacks = {
    wslay_event_frame_send_callback,
    wslay_event_frame_recv_callback,
    wslay_event_frame_genmask_callback
  };
  *ctx = (wslay_event_context_ptr)malloc(sizeof(struct wslay_event_context));
  if(!*ctx) {
    return WSLAY_ERR_NOMEM;
  }
  memset(*ctx, 0, sizeof(struct wslay_event_context));
  wslay_event_config_set_callbacks(*ctx, callbacks);
  (*ctx)->user_data = user_data;
  (*ctx)->frame_user_data.ctx = *ctx;
  (*ctx)->frame_user_data.user_data = user_data;
  if((r = wslay_frame_context_init(&(*ctx)->frame_ctx, &frame_callbacks,
                                   &(*ctx)->frame_user_data)) != 0) {
    wslay_event_context_free(*ctx);
    return r;
  }
  (*ctx)->read_enabled = (*ctx)->write_enabled = 1;
  (*ctx)->send_queue = wslay_queue_new();
  if(!(*ctx)->send_queue) {
    wslay_event_context_free(*ctx);
    return WSLAY_ERR_NOMEM;
  }
  (*ctx)->send_ctrl_queue = wslay_queue_new();
  if(!(*ctx)->send_ctrl_queue) {
    wslay_event_context_free(*ctx);
    return WSLAY_ERR_NOMEM;
  }
  (*ctx)->queued_msg_count = 0;
  (*ctx)->queued_msg_length = 0;
  for(i = 0; i < 2; ++i) {
    wslay_event_imsg_reset(&(*ctx)->imsgs[i]);
    (*ctx)->imsgs[i].chunks = wslay_queue_new();
    if(!(*ctx)->imsgs[i].chunks) {
      wslay_event_context_free(*ctx);
      return WSLAY_ERR_NOMEM;
    }
  }
  (*ctx)->imsg = &(*ctx)->imsgs[0];
  (*ctx)->obufmark = (*ctx)->obuflimit = (*ctx)->obuf;
  (*ctx)->status_code_sent = WSLAY_CODE_ABNORMAL_CLOSURE;
  (*ctx)->status_code_recv = WSLAY_CODE_ABNORMAL_CLOSURE;
  (*ctx)->max_recv_msg_length = (1u << 31)-1;
  return 0;
}
示例#2
0
websocket_return_t websocket_queue_close(websocket_t *websocket, const char *close_message)
{
	int r = WEBSOCKET_SUCCESS;

	if (websocket == NULL) {
		WEBSOCKET_DEBUG("NULL parameter\n");
		return WEBSOCKET_ALLOCATION_ERROR;
	}

	if (close_message == NULL) {
		close_message = "\0";
	}

	if (websocket->ctx != NULL && websocket->state != WEBSOCKET_STOP) {
		if (wslay_event_queue_close(websocket->ctx, 1000, (const uint8_t *)close_message, strlen(close_message)) != WEBSOCKET_SUCCESS) {
			WEBSOCKET_DEBUG("fail to queue close message\n");
			r = WEBSOCKET_SEND_ERROR;
			goto EXIT_QUEUE_CLOSE;
		}
		websocket_wait_state(websocket, WEBSOCKET_STOP, 100000);
		WEBSOCKET_DEBUG("websocket handler successfully stopped, closing\n");
	}

EXIT_QUEUE_CLOSE:
	WEBSOCKET_CLOSE(websocket->fd);

	if (websocket->ctx) {
		wslay_event_context_free(websocket->ctx);
		websocket->ctx = NULL;
	}

	websocket_update_state(websocket, WEBSOCKET_STOP);

	return r;
}
示例#3
0
void dslink_handshake_handle_ws(DSLink *link) {
    struct wslay_event_callbacks callbacks = {
        want_read_cb,
        want_write_cb,
        gen_mask_cb,
        NULL,
        NULL,
        NULL,
        recv_frame_cb
    };

    wslay_event_context_ptr ptr;
    if (wslay_event_context_client_init(&ptr, &callbacks, link) != 0) {
        return;
    }
    link->_ws = ptr;

    dslink_event_loop_init(&link->loop, io_handler, link);
    dslink_event_loop_sched(&link->loop, ping_handler, link);
    dslink_event_loop_process(&link->loop);

    dslink_event_loop_free(&link->loop);
    wslay_event_context_free(ptr);
    link->_ws = NULL;
}
示例#4
0
文件: websocket.c 项目: devnexen/h2o
void h2o_websocket_close(h2o_websocket_conn_t *conn)
{
    if (conn->sock != NULL)
        h2o_socket_close(conn->sock);
    free_write_buf(conn);
    wslay_event_context_free(conn->ws_ctx);
    free(conn);
}
示例#5
0
/*
 * if websocket server is initiated from http(s), you just can call this function.
 * see the comment of websocket_server_open to know what is different.
 */
websocket_return_t websocket_server_init(websocket_t *server)
{
	int r = WEBSOCKET_SUCCESS;
	struct websocket_info_t *socket_data = NULL;

	if (server == NULL) {
		WEBSOCKET_DEBUG("NULL parameter\n");
		return WEBSOCKET_ALLOCATION_ERROR;
	}

	socket_data = calloc(1, sizeof(struct websocket_info_t));
	if (socket_data == NULL) {
		WEBSOCKET_DEBUG("fail to allocate memory\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_SERVER_INIT;
	}
	socket_data->data = server;

	if (wslay_event_context_server_init(&(server->ctx), server->cb, socket_data) != WEBSOCKET_SUCCESS) {
		WEBSOCKET_DEBUG("fail to initiate websocket server\n");
		r = WEBSOCKET_INIT_ERROR;
		goto EXIT_SERVER_INIT;
	}

	if (websocket_config_socket(server->fd) != WEBSOCKET_SUCCESS) {
		r = WEBSOCKET_SOCKET_ERROR;
		goto EXIT_SERVER_INIT;
	}

	WEBSOCKET_DEBUG("start websocket server handling loop\n");
	r = websocket_handler(server);

EXIT_SERVER_INIT:
	WEBSOCKET_CLOSE(server->fd);

	if (server->ctx) {
		wslay_event_context_free(server->ctx);
		server->ctx = NULL;
	}

	if (server->tls_enabled) {
		mbedtls_net_free(&(server->tls_net));
		mbedtls_ssl_free(server->tls_ssl);
		WEBSOCKET_FREE(server->tls_ssl);
	}

	websocket_update_state(server, WEBSOCKET_STOP);

	return r;
}
示例#6
0
HIDDEN void ws_end_channel(void *ws_ctx)
{
    struct ws_context *ctx = (struct ws_context *) ws_ctx;

    if (!ctx) return;
    
    wslay_event_context_free(ctx->event);
    buf_free(&ctx->log);

    if (ctx->cb_rock) ctx->data_cb(NULL, NULL, NULL, &ctx->cb_rock);

    if (ctx->pmce.deflate.zstrm) {
        inflateEnd(ctx->pmce.deflate.zstrm);
        free(ctx->pmce.deflate.zstrm);
    }

    free(ctx);
}
示例#7
0
websocket_return_t websocket_client_open(websocket_t *client, char *host, char *port, char *path)
{
	int fd = -1;
	int r = WEBSOCKET_SUCCESS;
	struct websocket_info_t *socket_data = NULL;
	struct sched_param ws_sparam;

	if (client == NULL || host == NULL || port == NULL || path == NULL) {
		WEBSOCKET_DEBUG("NULL parameter\n");
		return WEBSOCKET_ALLOCATION_ERROR;
	}

	websocket_update_state(client, WEBSOCKET_RUN_CLIENT);

	//TODO : all TLS initializing code will be moved from example to here

	if (websocket_connect(client, host, port) != WEBSOCKET_SUCCESS) {
		r = WEBSOCKET_CONNECT_ERROR;
		goto EXIT_CLIENT_OPEN;
	}
	fd = client->fd;

	if (websocket_client_handshake(client, host, port, path) != WEBSOCKET_SUCCESS) {
		WEBSOCKET_DEBUG("fail to http handshake\n");
		r = WEBSOCKET_HANDSHAKE_ERROR;
		goto EXIT_CLIENT_OPEN;
	}

	socket_data = malloc(sizeof(struct websocket_info_t));
	if (socket_data == NULL) {
		WEBSOCKET_DEBUG("fail to allocate memory\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_CLIENT_OPEN;
	}
	memset(socket_data, 0, sizeof(struct websocket_info_t));
	socket_data->data = client;

	if (wslay_event_context_client_init(&client->ctx, client->cb, socket_data) != WEBSOCKET_SUCCESS) {
		WEBSOCKET_DEBUG("fail to init websocket client context\n");
		WEBSOCKET_FREE(socket_data);
		r = WEBSOCKET_INIT_ERROR;
		goto EXIT_CLIENT_OPEN;
	}

	WEBSOCKET_DEBUG("start websocket client handling thread\n");

	if (pthread_attr_init(&client->thread_attr) != 0) {
		WEBSOCKET_DEBUG("fail to init pthread attribute\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_CLIENT_OPEN;
	}

	if (pthread_attr_setstacksize(&client->thread_attr, WEBSOCKET_STACKSIZE) != 0) {
		WEBSOCKET_DEBUG("fail to set stack size\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_CLIENT_OPEN;
	}
	ws_sparam.sched_priority = WEBSOCKET_PRI;

	if (pthread_attr_setschedparam(&client->thread_attr, &ws_sparam) != 0) {
		WEBSOCKET_DEBUG("fail to set priority\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_CLIENT_OPEN;
	}

	if (pthread_attr_setschedpolicy(&client->thread_attr, WEBSOCKET_SCHED_POLICY) != 0) {
		WEBSOCKET_DEBUG("fail to set scheduler policy\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_CLIENT_OPEN;
	}

	if (pthread_create(&client->thread_id, &client->thread_attr, (pthread_startroutine_t) websocket_handler, (pthread_addr_t) client) != 0) {
		WEBSOCKET_DEBUG("fail to create websocket client thread\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_CLIENT_OPEN;
	}

	if (pthread_setname_np(client->thread_id, "websocket client handler") != 0) {
		WEBSOCKET_DEBUG("fail to set thread name\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_CLIENT_OPEN;
	}

	if (pthread_detach(client->thread_id) != 0) {
		WEBSOCKET_DEBUG("fail to detach websocket handler thread\n");
		r = WEBSOCKET_ALLOCATION_ERROR;
		goto EXIT_CLIENT_OPEN;
	}

	return r;

EXIT_CLIENT_OPEN:
	WEBSOCKET_CLOSE(fd);

	if (client->ctx) {
		wslay_event_context_free(client->ctx);
		client->ctx = NULL;
	}

	websocket_update_state(client, WEBSOCKET_STOP);

	return r;
}
示例#8
0
 ~WebSocketClient()
 {
   wslay_event_context_free(ctx_);
   shutdown(fd_, SHUT_WR);
   close(fd_);
 }