/*
    Copyright (c) 2013 250bpm s.r.o.  All rights reserved.
    Copyright (c) 2014-2016 Jack R. Dunaway. All rights reserved.
    Copyright 2016 Garrett D'Amore <garrett@damore.org>

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom
    the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    IN THE SOFTWARE.
*/

#include "sws.h"
#include "../../ws.h"
#include "../../nn.h"

#include "../../utils/alloc.h"
#include "../../utils/err.h"
#include "../../utils/cont.h"
#include "../../utils/fast.h"
#include "../../utils/wire.h"
#include "../../utils/attr.h"
#include "../../utils/random.h"

/*  States of the object as a whole. */
#define NN_SWS_STATE_IDLE 1
#define NN_SWS_STATE_HANDSHAKE 2
#define NN_SWS_STATE_STOPPING_HANDSHAKE 3
#define NN_SWS_STATE_ACTIVE 4
#define NN_SWS_STATE_CLOSING_CONNECTION 5
#define NN_SWS_STATE_BROKEN_CONNECTION 6
#define NN_SWS_STATE_DONE 7
#define NN_SWS_STATE_STOPPING 8

/*  Possible states of the inbound part of the object. */
#define NN_SWS_INSTATE_RECV_HDR 1
#define NN_SWS_INSTATE_RECV_HDREXT 2
#define NN_SWS_INSTATE_RECV_PAYLOAD 3
#define NN_SWS_INSTATE_RECVD_CHUNKED 4
#define NN_SWS_INSTATE_RECVD_CONTROL 5
#define NN_SWS_INSTATE_FAILING 6
#define NN_SWS_INSTATE_CLOSED 7

/*  Possible states of the outbound part of the object. */
#define NN_SWS_OUTSTATE_IDLE 1
#define NN_SWS_OUTSTATE_SENDING 2

/*  Subordinate srcptr objects. */
#define NN_SWS_SRC_USOCK 1
#define NN_SWS_SRC_HANDSHAKE 2

/*  WebSocket opcode constants as per RFC 6455 5.2. */
#define NN_WS_OPCODE_FRAGMENT 0x00
#define NN_WS_OPCODE_TEXT NN_WS_MSG_TYPE_TEXT
#define NN_WS_OPCODE_BINARY NN_WS_MSG_TYPE_BINARY
#define NN_WS_OPCODE_UNUSED3 0x03
#define NN_WS_OPCODE_UNUSED4 0x04
#define NN_WS_OPCODE_UNUSED5 0x05
#define NN_WS_OPCODE_UNUSED6 0x06
#define NN_WS_OPCODE_UNUSED7 0x07
#define NN_WS_OPCODE_CLOSE 0x08
#define NN_WS_OPCODE_PING 0x09
#define NN_WS_OPCODE_PONG 0x0A
#define NN_WS_OPCODE_UNUSEDB 0x0B
#define NN_WS_OPCODE_UNUSEDC 0x0C
#define NN_WS_OPCODE_UNUSEDD 0x0D
#define NN_WS_OPCODE_UNUSEDE 0x0E
#define NN_WS_OPCODE_UNUSEDF 0x0F

/*  WebSocket protocol header bit masks as per RFC 6455. */
#define NN_SWS_FRAME_BITMASK_MASKED 0x80
#define NN_SWS_FRAME_BITMASK_NOT_MASKED 0x00
#define NN_SWS_FRAME_BITMASK_LENGTH 0x7F

/*  WebSocket Close Status Codes (1004-1006 and 1015 are reserved). */
#define NN_SWS_CLOSE_NORMAL 1000
#define NN_SWS_CLOSE_GOING_AWAY 1001
#define NN_SWS_CLOSE_ERR_PROTO 1002
#define NN_SWS_CLOSE_ERR_WUT 1003
#define NN_SWS_CLOSE_ERR_INVALID_FRAME 1007
#define NN_SWS_CLOSE_ERR_POLICY 1008
#define NN_SWS_CLOSE_ERR_TOOBIG 1009
#define NN_SWS_CLOSE_ERR_EXTENSION 1010
#define NN_SWS_CLOSE_ERR_SERVER 1011

/*  UTF-8 validation. */
#define NN_SWS_UTF8_INVALID -2
#define NN_SWS_UTF8_FRAGMENT -1

/*  Stream is a special type of pipe. Implementation of the virtual pipe API. */
static int nn_sws_send (struct nn_pipebase *self, struct nn_msg *msg);
static int nn_sws_recv (struct nn_pipebase *self, struct nn_msg *msg);
const struct nn_pipebase_vfptr nn_sws_pipebase_vfptr = {
    nn_sws_send,
    nn_sws_recv
};

/*  Private functions. */
static void nn_sws_handler (struct nn_fsm *self, int src, int type,
    void *srcptr);
static void nn_sws_shutdown (struct nn_fsm *self, int src, int type,
    void *srcptr);

/*  Ceases further I/O on the underlying socket and prepares to send a
    close handshake on the next receive. */
static void nn_sws_fail_conn (struct nn_sws *self, int code, char *reason);

/*  Start receiving new message chunk. */
static int nn_sws_recv_hdr (struct nn_sws *self);

/*  Mask or unmask message payload. */
static void nn_sws_mask_payload (uint8_t *payload, size_t payload_len,
    const uint8_t *mask, size_t mask_len, int *mask_start_pos);

/*  Validates incoming text chunks for UTF-8 compliance as per RFC 3629. */
static void nn_sws_validate_utf8_chunk (struct nn_sws *self);

/*  Ensures that Close frames received from peer conform to
    RFC 6455 section 7. */
static void nn_sws_acknowledge_close_handshake (struct nn_sws *self);

void nn_sws_init (struct nn_sws *self, int src,
    struct nn_ep *ep, struct nn_fsm *owner)
{
    nn_fsm_init (&self->fsm, nn_sws_handler, nn_sws_shutdown,
        src, self, owner);
    self->state = NN_SWS_STATE_IDLE;
    nn_ws_handshake_init (&self->handshaker,
        NN_SWS_SRC_HANDSHAKE, &self->fsm);
    self->usock = NULL;
    self->usock_owner.src = -1;
    self->usock_owner.fsm = NULL;
    nn_pipebase_init (&self->pipebase, &nn_sws_pipebase_vfptr, ep);
    self->instate = -1;
    nn_list_init (&self->inmsg_array);
    self->outstate = -1;
    nn_msg_init (&self->outmsg, 0);

    self->continuing = 0;

    memset (self->utf8_code_pt_fragment, 0,
        NN_SWS_UTF8_MAX_CODEPOINT_LEN);
    self->utf8_code_pt_fragment_len = 0;

    self->pings_sent = 0;
    self->pongs_sent = 0;
    self->pings_received = 0;
    self->pongs_received = 0;

    nn_fsm_event_init (&self->done);
}

void nn_sws_term (struct nn_sws *self)
{
    nn_assert_state (self, NN_SWS_STATE_IDLE);

    nn_fsm_event_term (&self->done);
    nn_msg_term (&self->outmsg);
    nn_msg_array_term (&self->inmsg_array);
    nn_pipebase_term (&self->pipebase);
    nn_ws_handshake_term (&self->handshaker);
    nn_fsm_term (&self->fsm);
}

int nn_sws_isidle (struct nn_sws *self)
{
    return nn_fsm_isidle (&self->fsm);
}

void nn_sws_start (struct nn_sws *self, struct nn_usock *usock, int mode,
    const char *resource, const char *host, uint8_t msg_type)
{
    /*  Take ownership of the underlying socket. */
    nn_assert (self->usock == NULL && self->usock_owner.fsm == NULL);
    self->usock_owner.src = NN_SWS_SRC_USOCK;
    self->usock_owner.fsm = &self->fsm;
    nn_usock_swap_owner (usock, &self->usock_owner);
    self->usock = usock;
    self->mode = mode;
    self->resource = resource;
    self->remote_host = host;

    self->msg_type = msg_type;

    /*  Launch the state machine. */
    nn_fsm_start (&self->fsm);
}

void nn_sws_stop (struct nn_sws *self)
{
    nn_fsm_stop (&self->fsm);
}

void *nn_msg_chunk_new (size_t size, struct nn_list *msg_array)
{
    struct msg_chunk *self;

    self = nn_alloc (sizeof (struct msg_chunk), "msg_chunk");
    alloc_assert (self);

    nn_chunkref_init (&self->chunk, size);
    nn_list_item_init (&self->item);

    nn_list_insert (msg_array, &self->item, nn_list_end (msg_array));

    return nn_chunkref_data (&self->chunk);
}

void nn_msg_chunk_term (struct msg_chunk *it, struct nn_list *msg_array)
{
    nn_chunkref_term (&it->chunk);
    nn_list_erase (msg_array, &it->item);
    nn_list_item_term (&it->item);
    nn_free (it);
}

void nn_msg_array_term (struct nn_list *msg_array)
{
    struct nn_list_item *it;
    struct msg_chunk *ch;

    while (!nn_list_empty (msg_array)) {
        it = nn_list_begin (msg_array);
        ch = nn_cont (it, struct msg_chunk, item);
        nn_msg_chunk_term (ch, msg_array);
    }

    nn_list_term (msg_array);
}

/*  Given a buffer location, this function determines whether the leading
    octets form a valid UTF-8 code point. */
static int nn_utf8_code_point (const uint8_t *buffer, size_t len)
{
    /*  The lack of information is considered neither valid nor invalid. */
    if (!buffer || !len)
        return NN_SWS_UTF8_FRAGMENT;

    /*  RFC 3629 section 4 UTF8-1. */
    if (buffer [0] <= 0x7F)
        return 1;

    /*  0xC2, or 11000001, is the smallest conceivable multi-octet code
        point that is not an illegal overlong encoding. */
    if (buffer [0] < 0xC2)
        return NN_SWS_UTF8_INVALID;

    /*  Largest 2-octet code point starts with 0xDF (11011111). */
    if (buffer [0] <= 0xDF) {
        if (len < 2)
            return NN_SWS_UTF8_FRAGMENT;
        /*  Ensure continuation byte in form of 10xxxxxx */
        else if ((buffer [1] & 0xC0) != 0x80)
            return NN_SWS_UTF8_INVALID;
        else
            return 2;
    }

    /*  RFC 3629 section 4 UTF8-3, where 0xEF is 11101111. */
    if (buffer [0] <= 0xEF) {
        /*  Fragment. */
        if (len < 2)
            return NN_SWS_UTF8_FRAGMENT;
        /*  Illegal overlong sequence detection. */
        else if (buffer [0] == 0xE0 && (buffer [1] < 0xA0 || buffer [1] == 0x80))
            return NN_SWS_UTF8_INVALID;
        /*  Illegal UTF-16 surrogate pair half U+D800 through U+DFFF. */
        else if (buffer [0] == 0xED && buffer [1] >= 0xA0)
            return NN_SWS_UTF8_INVALID;
        /*  Fragment. */
        else if (len < 3)
            return NN_SWS_UTF8_FRAGMENT;
        /*  Ensure continuation bytes 2 and 3 in form of 10xxxxxx */
        else if ((buffer [1] & 0xC0) != 0x80 || (buffer [2] & 0xC0) != 0x80)
            return NN_SWS_UTF8_INVALID;
        else
            return 3;
    }

    /*  RFC 3629 section 4 UTF8-4, where 0xF4 is 11110100. Why
        not 11110111 to follow the pattern? Because UTF-8 encoding
        stops at 0x10FFFF as per RFC 3629. */
    if (buffer [0] <= 0xF4) {
        /*  Fragment. */
        if (len < 2)
            return NN_SWS_UTF8_FRAGMENT;
        /*  Illegal overlong sequence detection. */
        else if (buffer [0] == 0xF0 && buffer [1] < 0x90)
            return NN_SWS_UTF8_INVALID;
        /*  Illegal code point greater than U+10FFFF. */
        else if (buffer [0] == 0xF4 && buffer [1] >= 0x90)
            return NN_SWS_UTF8_INVALID;
        /*  Fragment. */
        else if (len < 4)
            return NN_SWS_UTF8_FRAGMENT;
        /*  Ensure continuation bytes 2, 3, and 4 in form of 10xxxxxx */
        else if ((buffer [1] & 0xC0) != 0x80 ||
            (buffer [2] & 0xC0) != 0x80 ||
            (buffer [3] & 0xC0) != 0x80)
            return NN_SWS_UTF8_INVALID;
        else
            return 4;
    }

    /*  UTF-8 encoding stops at U+10FFFF and only defines up to 4-octet
        code point sequences. */
    if (buffer [0] >= 0xF5)
        return NN_SWS_UTF8_INVALID;

    /*  Algorithm error; a case above should have been satisfied. */
    nn_assert (0);
}

static void nn_sws_mask_payload (uint8_t *payload, size_t payload_len,
    const uint8_t *mask, size_t mask_len, int *mask_start_pos)
{
    unsigned i;

    if (mask_start_pos) {
        for (i = 0; i < payload_len; i++) {
            payload [i] ^= mask [(i + *mask_start_pos) % mask_len];
        }

        *mask_start_pos = (i + *mask_start_pos) % mask_len;

        return;
    }
    else {
        for (i = 0; i < payload_len; i++) {
            payload [i] ^= mask [i % mask_len];
        }
        return;
    }
}

static int nn_sws_recv_hdr (struct nn_sws *self)
{
    if (!self->continuing) {
        nn_assert (nn_list_empty (&self->inmsg_array));

        self->inmsg_current_chunk_buf = NULL;
        self->inmsg_chunks = 0;
        self->inmsg_current_chunk_len = 0;
        self->inmsg_total_size = 0;
    }

    memset (self->inmsg_control, 0, NN_SWS_PAYLOAD_MAX_LENGTH);
    memset (self->inhdr, 0, NN_SWS_FRAME_MAX_HDR_LEN);
    self->instate = NN_SWS_INSTATE_RECV_HDR;
    nn_usock_recv (self->usock, self->inhdr, NN_SWS_FRAME_SIZE_INITIAL, NULL);

    return 0;
}

static int nn_sws_send (struct nn_pipebase *self, struct nn_msg *msg)
{
    struct nn_sws *sws;
    struct nn_iovec iov [3];
    int mask_pos;
    size_t nn_msg_size;
    size_t hdr_len;
    struct nn_cmsghdr *cmsg;
    struct nn_msghdr msghdr;
    uint8_t rand_mask [NN_SWS_FRAME_SIZE_MASK];

    sws = nn_cont (self, struct nn_sws, pipebase);

    nn_assert_state (sws, NN_SWS_STATE_ACTIVE);
    nn_assert (sws->outstate == NN_SWS_OUTSTATE_IDLE);

    /*  Move the message to the local storage. */
    nn_msg_term (&sws->outmsg);
    nn_msg_mv (&sws->outmsg, msg);

    memset (sws->outhdr, 0, sizeof (sws->outhdr));

    hdr_len = NN_SWS_FRAME_SIZE_INITIAL;

    cmsg = NULL;
    msghdr.msg_iov = NULL;
    msghdr.msg_iovlen = 0;
    msghdr.msg_controllen = nn_chunkref_size (&sws->outmsg.hdrs);

    /*  If the outgoing message has specified an opcode and control framing in
        its header, properly frame it as per RFC 6455 5.2. */
    if (msghdr.msg_controllen > 0) {
        msghdr.msg_control = nn_chunkref_data (&sws->outmsg.hdrs);
        cmsg = NN_CMSG_FIRSTHDR (&msghdr);
        while (cmsg) {
            if (cmsg->cmsg_level == NN_WS && cmsg->cmsg_type == NN_WS_MSG_TYPE)
                break;
            cmsg = NN_CMSG_NXTHDR (&msghdr, cmsg);
        }
    }

    /*  If the header does not specify an opcode, take default from option. */
    if (cmsg)
        sws->outhdr [0] = *(uint8_t *) NN_CMSG_DATA (cmsg);
    else
        sws->outhdr [0] = sws->msg_type;

    /*  For now, enforce that outgoing messages are the final frame. */
    sws->outhdr [0] |= NN_SWS_FRAME_BITMASK_FIN;

    nn_msg_size = nn_chunkref_size (&sws->outmsg.sphdr) +
        nn_chunkref_size (&sws->outmsg.body);

    /*  Framing WebSocket payload size in network byte order (big endian). */
    if (nn_msg_size <= NN_SWS_PAYLOAD_MAX_LENGTH) {
        sws->outhdr [1] |= (uint8_t) nn_msg_size;
        hdr_len += NN_SWS_FRAME_SIZE_PAYLOAD_0;
    }
    else if (nn_msg_size <= NN_SWS_PAYLOAD_MAX_LENGTH_16) {
        sws->outhdr [1] |= NN_SWS_PAYLOAD_FRAME_16;
        nn_puts (&sws->outhdr [hdr_len], (uint16_t) nn_msg_size);
        hdr_len += NN_SWS_FRAME_SIZE_PAYLOAD_16;
    }
    else {
        sws->outhdr [1] |= NN_SWS_PAYLOAD_FRAME_63;
        nn_putll (&sws->outhdr [hdr_len], (uint64_t) nn_msg_size);
        hdr_len += NN_SWS_FRAME_SIZE_PAYLOAD_63;
    }

    if (sws->mode == NN_WS_CLIENT) {
        sws->outhdr [1] |= NN_SWS_FRAME_BITMASK_MASKED;

        /*  Generate 32-bit mask as per RFC 6455 5.3. */
        nn_random_generate (rand_mask, NN_SWS_FRAME_SIZE_MASK);

        memcpy (&sws->outhdr [hdr_len], rand_mask, NN_SWS_FRAME_SIZE_MASK);
        hdr_len += NN_SWS_FRAME_SIZE_MASK;

        /*  Mask payload, beginning with header and moving to body. */
        mask_pos = 0;

        nn_sws_mask_payload (nn_chunkref_data (&sws->outmsg.sphdr),
            nn_chunkref_size (&sws->outmsg.sphdr),
            rand_mask, NN_SWS_FRAME_SIZE_MASK, &mask_pos);

        nn_sws_mask_payload (nn_chunkref_data (&sws->outmsg.body),
            nn_chunkref_size (&sws->outmsg.body),
            rand_mask, NN_SWS_FRAME_SIZE_MASK, &mask_pos);

    }
    else if (sws->mode == NN_WS_SERVER) {
        sws->outhdr [1] |= NN_SWS_FRAME_BITMASK_NOT_MASKED;
    }
    else {
        /*  Developer error; sws object was not constructed properly. */
        nn_assert (0);
    }

    /*  Start async sending. */
    iov [0].iov_base = sws->outhdr;
    iov [0].iov_len = hdr_len;
    iov [1].iov_base = nn_chunkref_data (&sws->outmsg.sphdr);
    iov [1].iov_len = nn_chunkref_size (&sws->outmsg.sphdr);
    iov [2].iov_base = nn_chunkref_data (&sws->outmsg.body);
    iov [2].iov_len = nn_chunkref_size (&sws->outmsg.body);
    nn_usock_send (sws->usock, iov, 3);

    sws->outstate = NN_SWS_OUTSTATE_SENDING;

    return 0;
}

static int nn_sws_recv (struct nn_pipebase *self, struct nn_msg *msg)
{
    struct nn_sws *sws;
    struct nn_list_item *it;
    struct msg_chunk *ch;
    struct nn_cmsghdr *cmsg;
    uint8_t opcode_hdr;
    uint8_t opcode;
    size_t cmsgsz;
    size_t pos;

    sws = nn_cont (self, struct nn_sws, pipebase);

    nn_assert_state (sws, NN_SWS_STATE_ACTIVE);

    switch (sws->instate) {
    case NN_SWS_INSTATE_RECVD_CHUNKED:

        /*  Relay opcode to the user in order to interpret payload. */
        opcode_hdr = sws->inmsg_hdr;

        /*  This library should not deliver fragmented messages to the
            application, so it's expected that this is the final frame. */
        nn_assert (sws->is_final_frame);
        nn_assert (opcode_hdr & NN_SWS_FRAME_BITMASK_FIN);
        opcode_hdr &= ~NN_SWS_FRAME_BITMASK_FIN;

        /*  The library is expected to have failed any connections with other
            opcodes; these are the only two opcodes that can be chunked. */
        opcode = opcode_hdr & NN_SWS_FRAME_BITMASK_OPCODE;
        nn_assert (opcode == NN_WS_OPCODE_BINARY ||
                   opcode == NN_WS_OPCODE_TEXT);

        nn_msg_init (msg, sws->inmsg_total_size);

        pos = 0;

        /*  Reassemble incoming message scatter array. */
        while (!nn_list_empty (&sws->inmsg_array)) {
            it = nn_list_begin (&sws->inmsg_array);
            ch = nn_cont (it, struct msg_chunk, item);
            memcpy (((uint8_t*) nn_chunkref_data (&msg->body)) + pos,
                nn_chunkref_data (&ch->chunk),
                nn_chunkref_size (&ch->chunk));
            pos += nn_chunkref_size (&ch->chunk);
            nn_msg_chunk_term (ch, &sws->inmsg_array);
        }

        nn_assert (pos == sws->inmsg_total_size);
        nn_assert (nn_list_empty (&sws->inmsg_array));

        /*  No longer collecting scatter array of incoming msg chunks. */
        sws->continuing = 0;

        nn_sws_recv_hdr (sws);

        break;

    case NN_SWS_INSTATE_RECVD_CONTROL:

        /*  Relay opcode to the user in order to interpret payload. */
        opcode_hdr = sws->inhdr [0];

        /*  This library should not deliver fragmented messages to the
            application, so it's expected that this is the final frame. */
        nn_assert (sws->is_final_frame);
        nn_assert (opcode_hdr & NN_SWS_FRAME_BITMASK_FIN);
        opcode_hdr &= ~NN_SWS_FRAME_BITMASK_FIN;

        /*  The library is expected to have failed any connections with other
            opcodes; these are the only two control opcodes delivered. */
        opcode = opcode_hdr & NN_SWS_FRAME_BITMASK_OPCODE;
        nn_assert (opcode == NN_WS_OPCODE_PING ||
                   opcode == NN_WS_OPCODE_PONG);

        nn_msg_init (msg, sws->inmsg_current_chunk_len);

        memcpy (((uint8_t*) nn_chunkref_data (&msg->body)),
            sws->inmsg_control, sws->inmsg_current_chunk_len);

        nn_sws_recv_hdr (sws);

        break;

    default:
        /*  Unexpected state. */
        nn_assert (0);
        break;
    }

    /*  Allocate and populate WebSocket-specific control headers. */
    cmsgsz = NN_CMSG_SPACE (sizeof (opcode_hdr));
    nn_chunkref_init (&msg->hdrs, cmsgsz);
    cmsg = nn_chunkref_data (&msg->hdrs);
    cmsg->cmsg_level = NN_WS;
    cmsg->cmsg_type = NN_WS_MSG_TYPE;
    cmsg->cmsg_len = cmsgsz;
    memcpy (NN_CMSG_DATA (cmsg), &opcode_hdr, sizeof (opcode_hdr));

    return 0;
}

static void nn_sws_validate_utf8_chunk (struct nn_sws *self)
{
    uint8_t *pos;
    int code_point_len;
    size_t len;

    len = self->inmsg_current_chunk_len;
    pos = self->inmsg_current_chunk_buf;

    /*  For chunked transfers, it's possible that a previous chunk was cut
        intra-code point. That partially-validated code point is reassembled
        with the beginning of the current chunk and checked. */
    if (self->utf8_code_pt_fragment_len) {

        nn_assert (self->utf8_code_pt_fragment_len <
            NN_SWS_UTF8_MAX_CODEPOINT_LEN);

        /*  Keep adding octets from fresh buffer to previous code point
            fragment to check for validity. */
        while (len > 0) {
            self->utf8_code_pt_fragment [self->utf8_code_pt_fragment_len] = *pos;
            self->utf8_code_pt_fragment_len++;
            pos++;
            len--;

            code_point_len = nn_utf8_code_point (self->utf8_code_pt_fragment,
                self->utf8_code_pt_fragment_len);

            if (code_point_len > 0) {
                /*  Valid code point found; continue validating. */
                break;
            }
            else if (code_point_len == NN_SWS_UTF8_INVALID) {
                nn_sws_fail_conn (self, NN_SWS_CLOSE_ERR_INVALID_FRAME,
                    "Invalid UTF-8 code point split on previous frame.");
                return;
            }
            else if (code_point_len == NN_SWS_UTF8_FRAGMENT) {
                if (self->is_final_frame) {
                    nn_sws_fail_conn (self, NN_SWS_CLOSE_ERR_INVALID_FRAME,
                        "Truncated UTF-8 payload with invalid code point.");
                    return;
                }
                else {
                    /*  This chunk is well-formed; now recv the next chunk. */
                    nn_sws_recv_hdr (self);
                    return;
                }
            }
        }
    }

    if (self->utf8_code_pt_fragment_len >= NN_SWS_UTF8_MAX_CODEPOINT_LEN)
        nn_assert (0);

    while (len > 0) {
        code_point_len = nn_utf8_code_point (pos, len);

        if (code_point_len > 0) {
            /*  Valid code point found; continue validating. */
            nn_assert (len >= (size_t) code_point_len);
            len -= code_point_len;
            pos += code_point_len;
            continue;
        }
        else if (code_point_len == NN_SWS_UTF8_INVALID) {
            self->utf8_code_pt_fragment_len = 0;
            memset (self->utf8_code_pt_fragment, 0,
                NN_SWS_UTF8_MAX_CODEPOINT_LEN);
            nn_sws_fail_conn (self, NN_SWS_CLOSE_ERR_INVALID_FRAME,
                "Invalid UTF-8 code point in payload.");
            return;
        }
        else if (code_point_len == NN_SWS_UTF8_FRAGMENT) {
            nn_assert (len < NN_SWS_UTF8_MAX_CODEPOINT_LEN);
            self->utf8_code_pt_fragment_len = len;
            memcpy (self->utf8_code_pt_fragment, pos, len);
            if (self->is_final_frame) {
                nn_sws_fail_conn (self, NN_SWS_CLOSE_ERR_INVALID_FRAME,
                    "Truncated UTF-8 payload with invalid code point.");
            }
            else {
                /*  Previous frame ended in the middle of a code point;
                    receive more. */
                nn_sws_recv_hdr (self);
            }
            return;
        }
    }

    /*  Entire buffer is well-formed. */
    nn_assert (len == 0);

    self->utf8_code_pt_fragment_len = 0;
    memset (self->utf8_code_pt_fragment, 0, NN_SWS_UTF8_MAX_CODEPOINT_LEN);

    if (self->is_final_frame) {
        self->instate = NN_SWS_INSTATE_RECVD_CHUNKED;
        nn_pipebase_received (&self->pipebase);
    }
    else {
        nn_sws_recv_hdr (self);
    }

    return;
}

static void nn_sws_acknowledge_close_handshake (struct nn_sws *self)
{
    uint8_t *pos;
    uint16_t close_code;
    int code_point_len;
    size_t len;

    len = self->inmsg_current_chunk_len;
    pos = self->inmsg_current_chunk_buf;

    /*  Peer did not provide a Close Code, so choose our own here. */
    if (len == 0) {
        nn_sws_fail_conn (self, NN_SWS_CLOSE_NORMAL, "");
        return;
    }

    /*  If the payload is not even long enough for the required 2-octet
        Close Code, the connection should have already been failed. */
    nn_assert (len >= NN_SWS_CLOSE_CODE_LEN);
    len -= NN_SWS_CLOSE_CODE_LEN;
    pos += NN_SWS_CLOSE_CODE_LEN;

    /*  As per RFC 6455 7.1.6, the Close Reason following the Close Code
        must be well-formed UTF-8. */
    while (len > 0) {
        code_point_len = nn_utf8_code_point (pos, len);

        if (code_point_len > 0) {
            /*  Valid code point found; continue validating. */
            nn_assert (len >= (size_t) code_point_len);
            len -= code_point_len;
            pos += code_point_len;
            continue;
        }
        else {
            /*  RFC 6455 7.1.6 */
            nn_sws_fail_conn (self, NN_SWS_CLOSE_ERR_PROTO,
                "Invalid UTF-8 sent as Close Reason.");
            return;
        }
    }

    /*  Entire Close Reason is well-formed UTF-8 (or empty) */
    nn_assert (len == 0);

    close_code = nn_gets (self->inmsg_current_chunk_buf);

    if (close_code == NN_SWS_CLOSE_NORMAL ||
        close_code == NN_SWS_CLOSE_GOING_AWAY ||
        close_code == NN_SWS_CLOSE_ERR_PROTO ||
        close_code == NN_SWS_CLOSE_ERR_WUT ||
        close_code == NN_SWS_CLOSE_ERR_INVALID_FRAME ||
        close_code == NN_SWS_CLOSE_ERR_POLICY ||
        close_code == NN_SWS_CLOSE_ERR_TOOBIG ||
        close_code == NN_SWS_CLOSE_ERR_EXTENSION ||
        close_code == NN_SWS_CLOSE_ERR_SERVER ||
        (close_code >= 3000 && close_code <= 3999) ||
        (close_code >= 4000 && close_code <= 4999)) {
        /*  Repeat close code, per RFC 6455 7.4.1 and 7.4.2 */
        nn_sws_fail_conn (self, (int) close_code, "");
    }
    else {
        nn_sws_fail_conn (self, NN_SWS_CLOSE_ERR_PROTO,
            "Unrecognized close code.");
    }

    return;
}

static void nn_sws_fail_conn (struct nn_sws *self, int code, char *reason)
{
    size_t reason_len;
    size_t payload_len;
    uint8_t rand_mask [NN_SWS_FRAME_SIZE_MASK];
    uint8_t *payload_pos;
    struct nn_iovec iov;

    nn_assert_state (self, NN_SWS_STATE_ACTIVE);

    /*  Stop user send/recv actions. */
    self->instate = NN_SWS_INSTATE_CLOSED;
    nn_pipebase_stop (&self->pipebase);

    /*  Destroy any remnant incoming message fragments. */
    nn_msg_array_term (&self->inmsg_array);

    reason_len = strlen (reason);

    payload_len = reason_len + NN_SWS_CLOSE_CODE_LEN;

    /*  Ensure text is short enough to also include code and framing. */
    nn_assert (payload_len <= NN_SWS_PAYLOAD_MAX_LENGTH);

    /*  RFC 6455 section 5.5.1. */
    self->fail_msg [0] = NN_SWS_FRAME_BITMASK_FIN | NN_WS_OPCODE_CLOSE;

    /*  Size of the payload, which is the status code plus the reason. */
    self->fail_msg [1] = (char)payload_len;

    self->fail_msg_len = NN_SWS_FRAME_SIZE_INITIAL;

    switch (self->mode) {
    case NN_WS_SERVER:
        self->fail_msg [1] |= NN_SWS_FRAME_BITMASK_NOT_MASKED;
        break;
    case NN_WS_CLIENT:
        self->fail_msg [1] |= NN_SWS_FRAME_BITMASK_MASKED;

        /*  Generate 32-bit mask as per RFC 6455 5.3. */
        nn_random_generate (rand_mask, NN_SWS_FRAME_SIZE_MASK);

        memcpy (&self->fail_msg [NN_SWS_FRAME_SIZE_INITIAL],
            rand_mask, NN_SWS_FRAME_SIZE_MASK);

        self->fail_msg_len += NN_SWS_FRAME_SIZE_MASK;
        break;
    default:
        /*  Developer error. */
        nn_assert (0);
    }

    payload_pos = (uint8_t*) (&self->fail_msg [self->fail_msg_len]);

    /*  Copy Status Code in network order (big-endian). */
    nn_puts (payload_pos, (uint16_t) code);
    self->fail_msg_len += NN_SWS_CLOSE_CODE_LEN;

    /*  Copy Close Reason immediately following the code. */
    memcpy (payload_pos + NN_SWS_CLOSE_CODE_LEN, reason, reason_len);
    self->fail_msg_len += reason_len;

    /*  If this is a client, apply mask. */
    if (self->mode == NN_WS_CLIENT) {
        nn_sws_mask_payload (payload_pos, payload_len,
            rand_mask, NN_SWS_FRAME_SIZE_MASK, NULL);
    }


    if (self->outstate == NN_SWS_OUTSTATE_IDLE) {
        iov.iov_base = self->fail_msg;
        iov.iov_len = self->fail_msg_len;
        nn_usock_send (self->usock, &iov, 1);
        self->outstate = NN_SWS_OUTSTATE_SENDING;
        self->state = NN_SWS_STATE_CLOSING_CONNECTION;
    } else {
        self->state = NN_SWS_STATE_DONE;
        nn_fsm_raise (&self->fsm, &self->done, NN_SWS_RETURN_CLOSE_HANDSHAKE);
    }

    return;
}

static void nn_sws_shutdown (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_sws *sws;

    sws = nn_cont (self, struct nn_sws, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        /*  TODO: Consider sending a close code here? */
        nn_pipebase_stop (&sws->pipebase);
        nn_ws_handshake_stop (&sws->handshaker);
        sws->state = NN_SWS_STATE_STOPPING;
    }
    if (nn_slow (sws->state == NN_SWS_STATE_STOPPING)) {
        if (nn_ws_handshake_isidle (&sws->handshaker)) {
            nn_usock_swap_owner (sws->usock, &sws->usock_owner);
            sws->usock = NULL;
            sws->usock_owner.src = -1;
            sws->usock_owner.fsm = NULL;
            sws->state = NN_SWS_STATE_IDLE;
            nn_fsm_stopped (&sws->fsm, NN_SWS_RETURN_STOPPED);
            return;
        }
        return;
    }

    nn_fsm_bad_state (sws->state, src, type);
}

static void nn_sws_handler (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_sws *sws;
    int rc;
    int opt;
    size_t opt_sz = sizeof (opt);

    sws = nn_cont (self, struct nn_sws, fsm);

    switch (sws->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/******************************************************************************/
    case NN_SWS_STATE_IDLE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                nn_ws_handshake_start (&sws->handshaker, sws->usock,
                    &sws->pipebase, sws->mode, sws->resource, sws->remote_host);
                sws->state = NN_SWS_STATE_HANDSHAKE;
                return;
            default:
                nn_fsm_bad_action (sws->state, src, type);
            }

        default:
            nn_fsm_bad_source (sws->state, src, type);
        }

/******************************************************************************/
/*  HANDSHAKE state.                                                          */
/******************************************************************************/
    case NN_SWS_STATE_HANDSHAKE:
        switch (src) {

        case NN_SWS_SRC_HANDSHAKE:
            switch (type) {
            case NN_WS_HANDSHAKE_OK:

                /*  Before moving to the active state stop the handshake
                    state machine. */
                nn_ws_handshake_stop (&sws->handshaker);
                sws->state = NN_SWS_STATE_STOPPING_HANDSHAKE;
                return;

            case NN_WS_HANDSHAKE_ERROR:

                /* Raise the error and move directly to the DONE state.
                   ws_handshake object will be stopped later on. */
                sws->state = NN_SWS_STATE_DONE;
                nn_fsm_raise (&sws->fsm, &sws->done,
                    NN_SWS_RETURN_CLOSE_HANDSHAKE);
                return;

            default:
                nn_fsm_bad_action (sws->state, src, type);
            }

        default:
            nn_fsm_bad_source (sws->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_HANDSHAKE state.                                                 */
/******************************************************************************/
    case NN_SWS_STATE_STOPPING_HANDSHAKE:
        switch (src) {

        case NN_SWS_SRC_HANDSHAKE:
            switch (type) {
            case NN_WS_HANDSHAKE_STOPPED:

                 /*  Start the pipe. */
                 rc = nn_pipebase_start (&sws->pipebase);
                 if (nn_slow (rc < 0)) {
                    sws->state = NN_SWS_STATE_DONE;
                    nn_fsm_raise (&sws->fsm, &sws->done, NN_SWS_RETURN_ERROR);
                    return;
                 }

                 /*  Start receiving a message in asynchronous manner. */
                 nn_sws_recv_hdr (sws);

                 /*  Mark the pipe as available for sending. */
                 sws->outstate = NN_SWS_OUTSTATE_IDLE;

                 sws->state = NN_SWS_STATE_ACTIVE;
                 return;

            default:
                nn_fsm_bad_action (sws->state, src, type);
            }

        default:
            nn_fsm_bad_source (sws->state, src, type);
        }

/******************************************************************************/
/*  ACTIVE state.                                                             */
/******************************************************************************/
    case NN_SWS_STATE_ACTIVE:
        switch (src) {

        case NN_SWS_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SENT:

                /*  The message is now fully sent. */
                nn_assert (sws->outstate == NN_SWS_OUTSTATE_SENDING);
                sws->outstate = NN_SWS_OUTSTATE_IDLE;
                nn_msg_term (&sws->outmsg);
                nn_msg_init (&sws->outmsg, 0);
                nn_pipebase_sent (&sws->pipebase);
                return;

            case NN_USOCK_RECEIVED:

                switch (sws->instate) {
                case NN_SWS_INSTATE_RECV_HDR:

                    /*  Require RSV1, RSV2, and RSV3 bits to be unset for
                        x-nanomsg protocol as per RFC 6455 section 5.2. */
                    if (sws->inhdr [0] & NN_SWS_FRAME_BITMASK_RSV1 ||
                        sws->inhdr [0] & NN_SWS_FRAME_BITMASK_RSV2 ||
                        sws->inhdr [0] & NN_SWS_FRAME_BITMASK_RSV3) {
                        nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                            "RSV1, RSV2, and RSV3 must be unset.");
                        return;
                    }

                    sws->is_final_frame = sws->inhdr [0] &
                        NN_SWS_FRAME_BITMASK_FIN;
                    sws->masked = sws->inhdr [1] &
                        NN_SWS_FRAME_BITMASK_MASKED;

                    switch (sws->mode) {
                    case NN_WS_SERVER:
                        /*  Require mask bit to be set from client. */
                        if (sws->masked) {
                            /*  Continue receiving header for this frame. */
                            sws->ext_hdr_len = NN_SWS_FRAME_SIZE_MASK;
                            break;
                        }
                        else {
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Server expects MASK bit to be set.");
                            return;
                        }
                    case NN_WS_CLIENT:
                        /*  Require mask bit to be unset from server. */
                        if (sws->masked) {
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Client expects MASK bit to be unset.");
                            return;
                        }
                        else {
                            /*  Continue receiving header for this frame. */
                            sws->ext_hdr_len = 0;
                            break;
                        }
                    default:
                        /*  Only two modes of this endpoint are expected. */
                        nn_assert (0);
                        return;
                    }

                    sws->opcode = sws->inhdr [0] &
                        NN_SWS_FRAME_BITMASK_OPCODE;
                    sws->payload_ctl = sws->inhdr [1] &
                        NN_SWS_FRAME_BITMASK_LENGTH;

                    /*  Prevent unexpected continuation frame. */
                    if (!sws->continuing &&
                        sws->opcode == NN_WS_OPCODE_FRAGMENT) {
                        nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                            "No message to continue.");
                        return;
                    }

                    /*  Preserve initial message opcode and RSV bits in case
                        this is a fragmented message. */
                    if (!sws->continuing)
                        sws->inmsg_hdr = sws->inhdr [0] |
                        NN_SWS_FRAME_BITMASK_FIN;

                    if (sws->payload_ctl <= NN_SWS_PAYLOAD_MAX_LENGTH) {
                        sws->ext_hdr_len += NN_SWS_FRAME_SIZE_PAYLOAD_0;
                    }
                    else if (sws->payload_ctl == NN_SWS_PAYLOAD_FRAME_16) {
                        sws->ext_hdr_len += NN_SWS_FRAME_SIZE_PAYLOAD_16;
                    }
                    else if (sws->payload_ctl == NN_SWS_PAYLOAD_FRAME_63) {
                        sws->ext_hdr_len += NN_SWS_FRAME_SIZE_PAYLOAD_63;
                    }
                    else {
                        /*  Developer error parsing/handling length. */
                        nn_assert (0);
                        return;
                    }

                    switch (sws->opcode) {

                    case NN_WS_OPCODE_TEXT:
                        /*  Fall thru; TEXT and BINARY handled alike. */
                    case NN_WS_OPCODE_BINARY:

                        sws->is_control_frame = 0;

                        if (sws->continuing) {
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Expected continuation frame opcode.");
                            return;
                        }

                        if (!sws->is_final_frame)
                            sws->continuing = 1;

                        if (sws->ext_hdr_len == 0 && sws->payload_ctl == 0) {
                            /*  Only a remote server could send a 2-byte msg;
                                sanity-check that this endpoint is a client. */
                            nn_assert (sws->mode == NN_WS_CLIENT);

                            sws->inmsg_current_chunk_len = 0;

                            if (sws->continuing) {
                                /*  This frame was empty, but continue
                                    next frame in fragmented sequence. */
                                nn_sws_recv_hdr (sws);
                                return;
                            }
                            else {
                                /*  Special case when there is no payload,
                                    mask, or additional frames. */
                                sws->instate = NN_SWS_INSTATE_RECVD_CHUNKED;
                                nn_pipebase_received (&sws->pipebase);
                                return;
                            }
                            }
                        /*  Continue to receive extended header+payload. */
                        break;

                    case NN_WS_OPCODE_FRAGMENT:

                        sws->is_control_frame = 0;
                        sws->continuing = !sws->is_final_frame;

                        if (sws->ext_hdr_len == 0 && sws->payload_ctl == 0) {
                            /*  Only a remote server could send a 2-byte msg;
                                sanity-check that this endpoint is a client. */
                            nn_assert (sws->mode == NN_WS_CLIENT);

                            sws->inmsg_current_chunk_len = 0;

                            if (sws->continuing) {
                                /*  This frame was empty, but continue
                                    next frame in fragmented sequence. */
                                nn_sws_recv_hdr (sws);
                                return;
                            }
                            else {
                                /*  Special case when there is no payload,
                                    mask, or additional frames. */
                                sws->instate = NN_SWS_INSTATE_RECVD_CHUNKED;
                                nn_pipebase_received (&sws->pipebase);
                                return;
                            }
                        }
                        /*  Continue to receive extended header+payload. */
                        break;

                    case NN_WS_OPCODE_PING:
                        sws->is_control_frame = 1;
                        sws->pings_received++;
                        if (sws->payload_ctl > NN_SWS_PAYLOAD_MAX_LENGTH) {
                            /*  As per RFC 6455 section 5.4, large payloads on
                                control frames is not allowed, and on receipt the
                                endpoint MUST close connection immediately. */
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Control frame payload exceeds allowable length.");
                            return;
                        }
                        if (!sws->is_final_frame) {
                            /*  As per RFC 6455 section 5.4, fragmentation of
                                control frames is not allowed; on receipt the
                                endpoint MUST close connection immediately. */
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Cannot fragment control message (FIN=0).");
                            return;
                        }

                        if (sws->ext_hdr_len == 0 && sws->payload_ctl == 0) {
                            /*  Special case when there is no payload,
                                mask, or additional frames. */
                            sws->inmsg_current_chunk_len = 0;
                            sws->instate = NN_SWS_INSTATE_RECVD_CONTROL;
                            nn_pipebase_received (&sws->pipebase);
                            return;
                        }
                        /*  Continue to receive extended header+payload. */
                        break;

                    case NN_WS_OPCODE_PONG:
                        sws->is_control_frame = 1;
                        sws->pongs_received++;
                        if (sws->payload_ctl > NN_SWS_PAYLOAD_MAX_LENGTH) {
                            /*  As per RFC 6455 section 5.4, large payloads on
                                control frames is not allowed, and on receipt the
                                endpoint MUST close connection immediately. */
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Control frame payload exceeds allowable length.");
                            return;
                        }
                        if (!sws->is_final_frame) {
                            /*  As per RFC 6455 section 5.4, fragmentation of
                                control frames is not allowed; on receipt the
                                endpoint MUST close connection immediately. */
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Cannot fragment control message (FIN=0).");
                            return;
                        }

                        if (sws->ext_hdr_len == 0 && sws->payload_ctl == 0) {
                            /*  Special case when there is no payload,
                                mask, or additional frames. */
                            sws->inmsg_current_chunk_len = 0;
                            sws->instate = NN_SWS_INSTATE_RECVD_CONTROL;
                            nn_pipebase_received (&sws->pipebase);
                            return;
                        }
                        /*  Continue to receive extended header+payload. */
                        break;

                    case NN_WS_OPCODE_CLOSE:
                        /*  RFC 6455 section 5.5.1. */
                        sws->is_control_frame = 1;
                        if (!sws->is_final_frame) {
                            /*  As per RFC 6455 section 5.4, fragmentation of
                                control frames is not allowed; on receipt the
                                endpoint MUST close connection immediately. */
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Cannot fragment control message (FIN=0).");
                            return;
                        }

                        if (sws->payload_ctl > NN_SWS_PAYLOAD_MAX_LENGTH) {
                            /*  As per RFC 6455 section 5.4, large payloads on
                                control frames is not allowed, and on receipt the
                                endpoint MUST close connection immediately. */
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Control frame payload exceeds allowable length.");
                            return;
                        }

                        if (sws->payload_ctl == 1) {
                            /*  As per RFC 6455 section 5.5.1, if a payload is
                                to accompany a close frame, the first two bytes
                                MUST be the close code. */
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Expected 2byte close code.");
                            return;
                        }

                        if (sws->ext_hdr_len == 0 && sws->payload_ctl == 0) {
                            /*  Special case when there is no payload,
                                mask, or additional frames. */
                            sws->inmsg_current_chunk_len = 0;
                            nn_sws_acknowledge_close_handshake (sws);
                            return;
                        }
                        /*  Continue to receive extended header+payload. */
                        break;

                    default:
                        /*  Client sent an invalid opcode; as per RFC 6455
                            section 10.7, close connection with code. */
                        nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Invalid opcode.");
                        return;

                    }

                    if (sws->ext_hdr_len == 0) {
                        /*  Only a remote server could send a 2-byte msg;
                            sanity-check that this endpoint is a client. */
                        nn_assert (sws->mode == NN_WS_CLIENT);

                        /*  In the case of no additional header, the payload
                            is known to be within these bounds. */
                        nn_assert (0 < sws->payload_ctl &&
                            sws->payload_ctl <= NN_SWS_PAYLOAD_MAX_LENGTH);

                        sws->inmsg_current_chunk_len = sws->payload_ctl;

                        /*  Use scatter/gather array for application messages,
                            and a fixed-width buffer for control messages. This
                            is convenient since control messages can be
                            interspersed between chunked application msgs. */
                        if (sws->is_control_frame) {
                            sws->inmsg_current_chunk_buf = sws->inmsg_control;
                        }
                        else {
                            sws->inmsg_total_size += sws->inmsg_current_chunk_len;
                            /*  Protect non-control messages against the
                                NN_RCVMAXSIZE threshold; control messages already
                                have a small pre-allocated buffer, and therefore
                                are not subject to this limit. */
                            nn_pipebase_getopt (&sws->pipebase, NN_SOL_SOCKET,
                                NN_RCVMAXSIZE, &opt, &opt_sz);
                            if (opt >= 0 && sws->inmsg_total_size > (size_t) opt) {
                                nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_TOOBIG,
                                    "Message larger than application allows.");
                                return;
                            }
                            sws->inmsg_chunks++;
                            sws->inmsg_current_chunk_buf =
                                nn_msg_chunk_new (sws->inmsg_current_chunk_len,
                                &sws->inmsg_array);
                        }

                        sws->instate = NN_SWS_INSTATE_RECV_PAYLOAD;
                        nn_usock_recv (sws->usock, sws->inmsg_current_chunk_buf,
                            sws->inmsg_current_chunk_len, NULL);
                        return;
                    }
                    else {
                        /*  Continue receiving the rest of the header frame. */
                        sws->instate = NN_SWS_INSTATE_RECV_HDREXT;
                        nn_usock_recv (sws->usock,
                            sws->inhdr + NN_SWS_FRAME_SIZE_INITIAL,
                            sws->ext_hdr_len,
                            NULL);
                        return;
                    }

                case NN_SWS_INSTATE_RECV_HDREXT:
                    nn_assert (sws->ext_hdr_len > 0);

                    if (sws->payload_ctl <= NN_SWS_PAYLOAD_MAX_LENGTH) {
                        sws->inmsg_current_chunk_len = sws->payload_ctl;
                        if (sws->masked) {
                            sws->mask = sws->inhdr + NN_SWS_FRAME_SIZE_INITIAL;
                        }
                        else {
                            sws->mask = NULL;
                        }
                    }
                    else if (sws->payload_ctl == NN_SWS_PAYLOAD_FRAME_16) {
                        sws->inmsg_current_chunk_len =
                            nn_gets (sws->inhdr + NN_SWS_FRAME_SIZE_INITIAL);
                        if (sws->masked) {
                            sws->mask = sws->inhdr +
                                NN_SWS_FRAME_SIZE_INITIAL +
                                NN_SWS_FRAME_SIZE_PAYLOAD_16;
                        }
                        else {
                            sws->mask = NULL;
                        }
                    }
                    else if (sws->payload_ctl == NN_SWS_PAYLOAD_FRAME_63) {
                        sws->inmsg_current_chunk_len =
                            (size_t) nn_getll (sws->inhdr +
                            NN_SWS_FRAME_SIZE_INITIAL);
                        if (sws->masked) {
                            sws->mask = sws->inhdr +
                                NN_SWS_FRAME_SIZE_INITIAL +
                                NN_SWS_FRAME_SIZE_PAYLOAD_63;
                        }
                        else {
                            sws->mask = NULL;
                        }
                    }
                    else {
                        /*  Client sent invalid data; as per RFC 6455,
                            server closes the connection immediately. */
                        nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_PROTO,
                                "Invalid payload length.");
                        return;
                    }

                    /*  Handle zero-length message bodies. */
                    if (sws->inmsg_current_chunk_len == 0) {
                        if (sws->is_final_frame) {
                            if (sws->opcode == NN_WS_OPCODE_CLOSE) {
                                nn_sws_acknowledge_close_handshake (sws);
                            }
                            else {
                                sws->instate = (sws->is_control_frame ?
                                    NN_SWS_INSTATE_RECVD_CONTROL :
                                    NN_SWS_INSTATE_RECVD_CHUNKED);
                                nn_pipebase_received (&sws->pipebase);
                            }
                        }
                        else {
                            nn_sws_recv_hdr (sws);
                        }
                        return;
                    }

                    nn_assert (sws->inmsg_current_chunk_len > 0);

                    /*  Use scatter/gather array for application messages,
                        and a fixed-width buffer for control messages. This
                        is convenient since control messages can be
                        interspersed between chunked application msgs. */
                    if (sws->is_control_frame) {
                        sws->inmsg_current_chunk_buf = sws->inmsg_control;
                    }
                    else {
                        sws->inmsg_total_size += sws->inmsg_current_chunk_len;
                        /*  Protect non-control messages against the
                            NN_RCVMAXSIZE threshold; control messages already
                            have a small pre-allocated buffer, and therefore
                            are not subject to this limit. */
                        nn_pipebase_getopt (&sws->pipebase, NN_SOL_SOCKET,
                            NN_RCVMAXSIZE, &opt, &opt_sz);
                        if (opt >= 0 && sws->inmsg_total_size > (size_t) opt) {
                            nn_sws_fail_conn (sws, NN_SWS_CLOSE_ERR_TOOBIG,
                                "Message size exceeds limit.");
                            return;
                        }
                        sws->inmsg_chunks++;
                        sws->inmsg_current_chunk_buf =
                            nn_msg_chunk_new (sws->inmsg_current_chunk_len,
                            &sws->inmsg_array);
                    }

                    sws->instate = NN_SWS_INSTATE_RECV_PAYLOAD;
                    nn_usock_recv (sws->usock, sws->inmsg_current_chunk_buf,
                        sws->inmsg_current_chunk_len, NULL);
                    return;

                case NN_SWS_INSTATE_RECV_PAYLOAD:

                    /*  Unmask if necessary. */
                    if (sws->masked) {
                        nn_sws_mask_payload (sws->inmsg_current_chunk_buf,
                            sws->inmsg_current_chunk_len, sws->mask,
                            NN_SWS_FRAME_SIZE_MASK, NULL);
                    }

                    switch (sws->opcode) {

                    case NN_WS_OPCODE_TEXT:
                        nn_sws_validate_utf8_chunk (sws);
                        return;

                    case NN_WS_OPCODE_BINARY:
                        if (sws->is_final_frame) {
                            sws->instate = NN_SWS_INSTATE_RECVD_CHUNKED;
                            nn_pipebase_received (&sws->pipebase);
                        }
                        else {
                            nn_sws_recv_hdr (sws);
                        }
                        return;

                    case NN_WS_OPCODE_FRAGMENT:
                        /*  Must check original opcode to see if this fragment
                            needs UTF-8 validation. */
                        if ((sws->inmsg_hdr & NN_SWS_FRAME_BITMASK_OPCODE) ==
                            NN_WS_OPCODE_TEXT) {
                            nn_sws_validate_utf8_chunk (sws);
                        }
                        else if (sws->is_final_frame) {
                            sws->instate = NN_SWS_INSTATE_RECVD_CHUNKED;
                            nn_pipebase_received (&sws->pipebase);
                        }
                        else {
                            nn_sws_recv_hdr (sws);
                        }
                        return;

                    case NN_WS_OPCODE_PING:
                        sws->instate = NN_SWS_INSTATE_RECVD_CONTROL;
                        nn_pipebase_received (&sws->pipebase);
                        return;

                    case NN_WS_OPCODE_PONG:
                        sws->instate = NN_SWS_INSTATE_RECVD_CONTROL;
                        nn_pipebase_received (&sws->pipebase);
                        return;

                    case NN_WS_OPCODE_CLOSE:
                        nn_sws_acknowledge_close_handshake (sws);
                        return;

                    default:
                        /*  This should have been prevented upstream. */
                        nn_assert (0);
                        return;
                    }

                default:
                    nn_fsm_error ("Unexpected socket instate",
                        sws->state, src, type);
                }

            case NN_USOCK_SHUTDOWN:
                nn_pipebase_stop (&sws->pipebase);
                sws->state = NN_SWS_STATE_BROKEN_CONNECTION;
                return;

            case NN_USOCK_ERROR:
                nn_pipebase_stop (&sws->pipebase);
                sws->state = NN_SWS_STATE_DONE;
                nn_fsm_raise (&sws->fsm, &sws->done, NN_SWS_RETURN_ERROR);
                return;

            default:
                nn_fsm_bad_action (sws->state, src, type);
            }

            break;

        default:
            nn_fsm_bad_source (sws->state, src, type);
        }

/******************************************************************************/
/*  CLOSING_CONNECTION state.                                                 */
/*  Wait for acknowledgement closing handshake was successfully sent.         */
/******************************************************************************/
    case NN_SWS_STATE_CLOSING_CONNECTION:
        switch (src) {

        case NN_SWS_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SENT:
                /*  Wait for acknowledgement closing handshake was sent
                    to peer. */
                nn_assert (sws->outstate == NN_SWS_OUTSTATE_SENDING);
                sws->outstate = NN_SWS_OUTSTATE_IDLE;
                sws->state = NN_SWS_STATE_DONE;
                nn_fsm_raise (&sws->fsm, &sws->done,
                    NN_SWS_RETURN_CLOSE_HANDSHAKE);
                return;
            case NN_USOCK_SHUTDOWN:
                return;
            case NN_USOCK_ERROR:
                sws->state = NN_SWS_STATE_DONE;
                nn_fsm_raise (&sws->fsm, &sws->done, NN_SWS_RETURN_ERROR);
                return;
            default:
                nn_fsm_bad_action (sws->state, src, type);
            }

        default:
            nn_fsm_bad_source (sws->state, src, type);
        }

/******************************************************************************/
/*  SHUTTING_DOWN state.                                                      */
/*  The underlying connection is closed. We are just waiting that underlying  */
/*  usock being closed                                                        */
/******************************************************************************/
    case NN_SWS_STATE_BROKEN_CONNECTION:
        switch (src) {

        case NN_SWS_SRC_USOCK:
            switch (type) {
            case NN_USOCK_ERROR:
                sws->state = NN_SWS_STATE_DONE;
                nn_fsm_raise (&sws->fsm, &sws->done, NN_SWS_RETURN_ERROR);
                return;
            default:
                nn_fsm_bad_action (sws->state, src, type);
            }

        default:
            nn_fsm_bad_source (sws->state, src, type);
        }

/******************************************************************************/
/*  DONE state.                                                               */
/*  The underlying connection is closed. There's nothing that can be done in  */
/*  this state except stopping the object.                                    */
/******************************************************************************/
    case NN_SWS_STATE_DONE:
        nn_fsm_bad_source (sws->state, src, type);

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (sws->state, src, type);
    }
}
