Intention is to make private in websockets.c and reduce changes in reds-stream.c --- server/reds-stream.c | 40 ++++------------------------------------ server/websocket.c | 42 ++++++++++++++++++++++++++++++++++-------- server/websocket.h | 24 +++++++++++++++++------- 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/server/reds-stream.c b/server/reds-stream.c index b59586b..bf0cbbe 100644 --- a/server/reds-stream.c +++ b/server/reds-stream.c @@ -78,17 +78,6 @@ typedef struct RedsSASL { } RedsSASL; #endif -typedef struct { - int closed; - - websocket_frame_t read_frame; - guint64 write_remainder; - - ssize_t (*raw_read)(RedsStream *s, void *buf, size_t nbyte); - ssize_t (*raw_write)(RedsStream *s, const void *buf, size_t nbyte); - ssize_t (*raw_writev)(RedsStream *s, const struct iovec *iov, int iovcnt); -} RedsWebSocket; - struct RedsStreamPrivate { SSL *ssl; @@ -1151,39 +1140,17 @@ error: static ssize_t stream_websocket_read(RedsStream *s, void *buf, size_t size) { - int rc; - - if (s->priv->ws->closed) - return 0; - - rc = websocket_read((void *)s, buf, size, &s->priv->ws->read_frame, - (websocket_write_cb_t) s->priv->ws->raw_read, - (websocket_write_cb_t) s->priv->ws->raw_write); - - if (rc == 0) - s->priv->ws->closed = 1; - - return rc; + return websocket_read(s->priv->ws, buf, size); } static ssize_t stream_websocket_write(RedsStream *s, const void *buf, size_t size) { - if (s->priv->ws->closed) { - errno = EPIPE; - return -1; - } - return websocket_write((void *)s, buf, size, &s->priv->ws->write_remainder, - (websocket_write_cb_t) s->priv->ws->raw_write); + return websocket_write(s->priv->ws, buf, size); } static ssize_t stream_websocket_writev(RedsStream *s, const struct iovec *iov, int iovcnt) { - if (s->priv->ws->closed) { - errno = EPIPE; - return -1; - } - return websocket_writev((void *)s, (struct iovec *) iov, iovcnt, &s->priv->ws->write_remainder, - (websocket_writev_cb_t) s->priv->ws->raw_writev); + return websocket_writev(s->priv->ws, (struct iovec *) iov, iovcnt); } /* @@ -1232,6 +1199,7 @@ bool reds_stream_is_websocket(RedsStream *stream, unsigned char *buf, int len) if (rc == strlen(outbuf)) { stream->priv->ws = spice_malloc0(sizeof(*stream->priv->ws)); + stream->priv->ws->raw_stream = stream; stream->priv->ws->raw_read = stream->priv->read; stream->priv->ws->raw_write = stream->priv->write; diff --git a/server/websocket.c b/server/websocket.c index 1379487..533fc06 100644 --- a/server/websocket.c +++ b/server/websocket.c @@ -216,20 +216,29 @@ static int relay_data(guint8* buf, size_t size, websocket_frame_t *frame) return n; } -int websocket_read(void *opaque, guchar *buf, int size, websocket_frame_t *frame, - websocket_read_cb_t read_cb, - websocket_write_cb_t write_cb) +int websocket_read(RedsWebSocket *ws, guchar *buf, int size) { int n = 0; int rc; + websocket_frame_t *frame = &ws->read_frame; + void *opaque = ws->raw_stream; + websocket_read_cb_t read_cb = (websocket_read_cb_t) ws->raw_read; + websocket_write_cb_t write_cb = (websocket_write_cb_t) ws->raw_write; + + if (ws->closed) { + return 0; + } while (size > 0) { if (! frame->frame_ready) { - rc = read_cb(opaque, frame->header + frame->header_pos, frame_bytes_needed(frame)); + rc = read_cb(ws->raw_stream, frame->header + frame->header_pos, frame_bytes_needed(frame)); if (rc <= 0) { if (n > 0 && rc == -1 && (errno == EINTR || errno == EAGAIN)) return n; + if (rc == 0) { + ws->closed = TRUE; + } return rc; } frame->header_pos += rc; @@ -238,6 +247,7 @@ int websocket_read(void *opaque, guchar *buf, int size, websocket_frame_t *frame } else if (frame->type == CLOSE_FRAME) { websocket_ack_close(opaque, write_cb); websocket_clear_frame(frame); + ws->closed = TRUE; return 0; } else if (frame->type == BINARY_FRAME) { rc = read_cb(opaque, buf, MIN(size, frame->expected_len - frame->relayed)); @@ -245,6 +255,9 @@ int websocket_read(void *opaque, guchar *buf, int size, websocket_frame_t *frame if (n > 0 && rc == -1 && (errno == EINTR || errno == EAGAIN)) return n; + if (rc == 0) { + ws->closed = TRUE; + } return rc; } @@ -323,8 +336,7 @@ static void constrain_iov(struct iovec *iov, int iovcnt, /* Write a WebSocket frame with the enclosed data out. */ -int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, guint64 *remainder, - websocket_writev_cb_t writev_cb) +int websocket_writev(RedsWebSocket *ws, struct iovec *iov, int iovcnt) { guint8 header[WEBSOCKET_MAX_HEADER_SIZE]; guint64 len; @@ -333,7 +345,14 @@ int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, guint64 *remai int iov_out_cnt; int i; int header_len; + void *opaque = ws->raw_stream; + websocket_writev_cb_t writev_cb = (websocket_writev_cb_t) ws->raw_writev; + guint64 *remainder = &ws->write_remainder; + if (ws->closed) { + errno = EPIPE; + return -1; + } if (*remainder > 0) { constrain_iov(iov, iovcnt, &iov_out, &iov_out_cnt, *remainder); rc = writev_cb(opaque, iov_out, iov_out_cnt); @@ -376,12 +395,19 @@ int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, guint64 *remai return rc; } -int websocket_write(void *opaque, const guchar *buf, int len, guint64 *remainder, - websocket_write_cb_t write_cb) +int websocket_write(RedsWebSocket *ws, const guchar *buf, int len) { guint8 header[WEBSOCKET_MAX_HEADER_SIZE]; int rc; int header_len; + void *opaque = ws->raw_stream; + websocket_write_cb_t write_cb = (websocket_write_cb_t) ws->raw_write; + guint64 *remainder = &ws->write_remainder; + + if (ws->closed) { + errno = EPIPE; + return -1; + } if (*remainder == 0) { header_len = fill_header(header, len); diff --git a/server/websocket.h b/server/websocket.h index 2306492..2eb3431 100644 --- a/server/websocket.h +++ b/server/websocket.h @@ -17,6 +17,8 @@ #define WEBSOCKET_MAX_HEADER_SIZE (1 + 9 + 4) +struct RedsStream; + typedef struct { int type; int masked; @@ -32,14 +34,22 @@ typedef ssize_t (*websocket_read_cb_t)(void *opaque, const void *buf, size_t nby typedef ssize_t (*websocket_write_cb_t)(void *opaque, const void *buf, size_t nbyte); typedef ssize_t (*websocket_writev_cb_t)(void *opaque, struct iovec *iov, int iovcnt); +typedef struct { + int closed; + + websocket_frame_t read_frame; + guint64 write_remainder; + + struct RedsStream *raw_stream; + ssize_t (*raw_read)(struct RedsStream *s, void *buf, size_t nbyte); + ssize_t (*raw_write)(struct RedsStream *s, const void *buf, size_t nbyte); + ssize_t (*raw_writev)(struct RedsStream *s, const struct iovec *iov, int iovcnt); +} RedsWebSocket; + bool websocket_is_start(gchar *buf); void websocket_create_reply(gchar *buf, gchar *outbuf); -int websocket_read(void *opaque, guchar *buf, int len, websocket_frame_t *frame, - websocket_read_cb_t read_cb, - websocket_write_cb_t write_cb); -int websocket_write(void *opaque, const guchar *buf, int len, guint64 *remainder, - websocket_write_cb_t write_cb); -int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, guint64 *remainder, - websocket_writev_cb_t writev_cb); +int websocket_read(RedsWebSocket *ws, guchar *buf, int len); +int websocket_write(RedsWebSocket *ws, const guchar *buf, int len); +int websocket_writev(RedsWebSocket *ws, struct iovec *iov, int iovcnt); void websocket_ack_close(void *opaque, websocket_write_cb_t write_cb); -- 2.7.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel