Exemple #1
0
int swSSL_accept(swConnection *conn)
{
    int n = SSL_do_handshake(conn->ssl);
    if (n == 1)
    {
        conn->ssl_state = SW_SSL_STATE_READY;
        if (conn->ssl->s3)
        {
            conn->ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
        }
        return SW_READY;
    }
    long err = SSL_get_error(conn->ssl, n);
    if (err == SSL_ERROR_WANT_READ)
    {
        return SW_WAIT;
    }
    else if (err == SSL_ERROR_WANT_WRITE)
    {
        return SW_WAIT;
    }
    else if (err == SSL_ERROR_SSL)
    {
        swWarn("bad SSL client[%s:%d] .", swConnection_get_ip(conn), swConnection_get_port(conn));
        return SW_ERROR;
    }
    else if (err == SSL_ERROR_SYSCALL)
    {
        swSysError("SSL error syscall.");
        return SW_ERROR;
    }
    swWarn("swSSL_accept() failed. Error: %s[%ld]", ERR_reason_error_string(err), err);
    return SW_ERROR;
}
int my_onReceive(swFactory *factory, swEventData *req)
{
    int ret;
    char resp_data[SW_BUFFER_SIZE];
    swServer *serv = factory->ptr;

    swSendData resp;
    g_receive_count++;
    memcpy(&resp.info, &req->info, sizeof(resp.info));

    printf("recv %d bytes, data=%s\n", req->info.len, req->data);

    int n = snprintf(resp_data, SW_BUFFER_SIZE, "Server: %*s", req->info.len, req->data);

    resp_data[n] = '\0';

    resp.data = resp_data;
    resp.info.len = n;
    resp.info.type = SW_EVENT_TCP;
    resp.length = 0;

    printf("send %d bytes. data=%s\n", n, resp_data);

    return SW_OK;

    ret = factory->finish(factory, &resp);
    if (ret < 0)
    {
        printf("send to client fail. errno=%d\n", errno);
    }

    if (req->info.from_id >= serv->reactor_num)
    {
        struct in_addr addr;
        addr.s_addr = req->info.fd;

        //printf("onReceive[%d]: ip=%s:%d, Data=%s\n", g_receive_count, inet_ntoa(addr), req->info.from_id, rtrim(req->data, req->info.len));
    }
    else
    {
        swConnection *conn = swWorker_get_connection(serv, req->info.fd);
        swoole_rtrim(req->data, req->info.len);
        printf("onReceive[%d]: ip=%s|port=%d Data=%s|Len=%d\n", g_receive_count, swConnection_get_ip(conn),
                swConnection_get_port(conn), req->data, req->info.len);
    }
//	req->info.type = 99;
//	factory->event(factory, g_controller_id, req);
    return SW_OK;
}
Exemple #3
0
int swSSL_accept(swConnection *conn)
{
    int n = SSL_do_handshake(conn->ssl);
    if (n == 1)
    {
        conn->ssl_state = SW_SSL_STATE_READY;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
        if (conn->ssl->s3)
        {
            conn->ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
        }
#endif
#endif
        return SW_READY;
    }
    long err = SSL_get_error(conn->ssl, n);
    if (err == SSL_ERROR_WANT_READ)
    {
        return SW_WAIT;
    }
    else if (err == SSL_ERROR_WANT_WRITE)
    {
        return SW_WAIT;
    }
    else if (err == SSL_ERROR_SSL)
    {
        swWarn("bad SSL client[%s:%d].", swConnection_get_ip(conn), swConnection_get_port(conn));
        return SW_ERROR;
    }
    //EOF was observed
    else if (err == SSL_ERROR_SYSCALL && n == 0)
    {
        return SW_ERROR;
    }
    swWarn("swSSL_accept() failed. Error: %s[%ld]", ERR_reason_error_string(err), err);
    return SW_ERROR;
}
Exemple #4
0
/**
 * return the package total length
 */
int swProtocol_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t size)
{
    uint16_t length_offset = protocol->package_length_offset;
    int32_t body_length;
    /**
     * no have length field, wait more data
     */
    if (size < length_offset + protocol->package_length_size)
    {
        return 0;
    }
    body_length = swoole_unpack(protocol->package_length_type, data + length_offset);
    //Length error
    //Protocol length is not legitimate, out of bounds or exceed the allocated length
    if (body_length < 0 || body_length > protocol->package_max_length)
    {
        swWarn("invalid package, remote_addr=%s:%d, length=%d, size=%d.", swConnection_get_ip(conn), swConnection_get_port(conn), body_length, size);
        return SW_ERR;
    }
    //total package length
    return protocol->package_body_offset + body_length;
}
Exemple #5
0
int swWebSocket_dispatch_frame(swConnection *conn, char *data, uint32_t length)
{
    swString frame;
    bzero(&frame, sizeof(frame));
    frame.str = data;
    frame.length = length;

    swString send_frame;
    bzero(&send_frame, sizeof(send_frame));
    char buf[128];
    send_frame.str = buf;
    send_frame.size = sizeof(buf);

    swWebSocket_frame ws;
    swWebSocket_decode(&ws, &frame);

    swString *frame_buffer;
    int frame_length;
    swListenPort *port;

    size_t offset;
    switch (ws.header.OPCODE)
    {
    case WEBSOCKET_OPCODE_CONTINUATION_FRAME:
        frame_buffer = conn->websocket_buffer;
        if (frame_buffer == NULL)
        {
            swWarn("bad frame[opcode=0]. remote_addr=%s:%d.", swConnection_get_ip(conn), swConnection_get_port(conn));
            return SW_ERR;
        }
        offset = length - ws.payload_length;
        frame_length = length - offset;
        port = swServer_get_port(SwooleG.serv, conn->fd);
        //frame data overflow
        if (frame_buffer->length + frame_length > port->protocol.package_max_length)
        {
            swWarn("websocket frame is too big, remote_addr=%s:%d.", swConnection_get_ip(conn), swConnection_get_port(conn));
            return SW_ERR;
        }
        //merge incomplete data
        swString_append_ptr(frame_buffer, data + offset, frame_length);
        //frame is finished, do dispatch
        if (ws.header.FIN)
        {
            swReactorThread_dispatch(conn, frame_buffer->str, frame_buffer->length);
            swString_free(frame_buffer);
            conn->websocket_buffer = NULL;
        }
        break;

    case WEBSOCKET_OPCODE_TEXT_FRAME:
    case WEBSOCKET_OPCODE_BINARY_FRAME:
        offset = length - ws.payload_length - 2;
        data[offset] = 1;
        data[offset + 1] = ws.header.OPCODE;
        if (!ws.header.FIN)
        {
            if (conn->websocket_buffer)
            {
                swWarn("merging incomplete frame, bad request. remote_addr=%s:%d.", swConnection_get_ip(conn), swConnection_get_port(conn));
                return SW_ERR;
            }
            conn->websocket_buffer = swString_dup(data + offset, length - offset);
        }
        else
        {
            swReactorThread_dispatch(conn, data + offset, length - offset);
        }
        break;

    case WEBSOCKET_OPCODE_PING:
        if (length >= (sizeof(buf) - 2))
        {
            swWarn("ping frame application data is too big. remote_addr=%s:%d.", swConnection_get_ip(conn), swConnection_get_port(conn));
            return SW_ERR;
        }
        else if (length == 2)
        {
            swWebSocket_encode(&send_frame, NULL, 0, WEBSOCKET_OPCODE_PONG, 1, 0);
        }
        else
        {
            swWebSocket_encode(&send_frame, data += 2, length - 2, WEBSOCKET_OPCODE_PONG, 1, 0);
        }
        swConnection_send(conn, send_frame.str, send_frame.length, 0);
        break;

    case WEBSOCKET_OPCODE_PONG:
        break;

    case WEBSOCKET_OPCODE_CONNECTION_CLOSE:
        if (0x7d < (length - 2))
        {
            return SW_ERR;
        }
        send_frame.str[0] = 0x88;
        send_frame.str[1] = 0x00;
        send_frame.length = 2;
        swConnection_send(conn, send_frame.str, 2, 0);
        return SW_ERR;

    default:
        swWarn("unknown opcode [%d].", ws.header.OPCODE);
        break;
    }
    return SW_OK;
}
Exemple #6
0
/**
 * @return SW_ERR: close the connection
 * @return SW_OK: continue
 */
int swProtocol_recv_check_length(swProtocol *protocol, swConnection *conn, swString *buffer)
{
    int package_length;
    uint32_t recv_size;
    char swap[SW_BUFFER_SIZE];

    do_recv:
    if (buffer->offset > 0)
    {
        recv_size = buffer->offset - buffer->length;
    }
    else
    {
        recv_size = protocol->package_length_offset + protocol->package_length_size;
    }

    int ret = swConnection_recv(conn, buffer->str + buffer->length, recv_size, 0);
    if (ret < 0)
    {
        switch (swConnection_error(errno))
        {
        case SW_ERROR:
            swSysError("recv(%d, %d) failed.", conn->fd, recv_size);
            return SW_OK;
        case SW_CLOSE:
            conn->close_errno = errno;
            return SW_ERR;
        default:
            return SW_OK;
        }
    }
    else if (ret == 0)
    {
        return SW_ERR;
    }
    else
    {
        buffer->length += ret;

        if (conn->recv_wait)
        {
            if (buffer->length >= buffer->offset)
            {
                do_dispatch:
                ret = protocol->onPackage(conn, buffer->str, buffer->offset);
                conn->recv_wait = 0;

                int remaining_length = buffer->length - buffer->offset;
                if (remaining_length > 0)
                {
                    assert(remaining_length < sizeof(swap));
                    memcpy(swap, buffer->str + buffer->offset, remaining_length);
                    memcpy(buffer->str, swap, remaining_length);
                    buffer->offset = 0;
                    buffer->length = remaining_length;
                    goto do_get_length;
                }
                else
                {
                    swString_clear(buffer);
                    return ret;
                }
            }
            else
            {
                return SW_OK;
            }
        }
        else
        {
            do_get_length: package_length = protocol->get_package_length(protocol, conn, buffer->str, buffer->length);
            //invalid package, close connection.
            if (package_length < 0)
            {
                return SW_ERR;
            }
            //no length
            else if (package_length == 0)
            {
                return SW_OK;
            }
            else if (package_length > protocol->package_max_length)
            {
                swWarn("package is too big, remote_addr=%s:%d, length=%d.", swConnection_get_ip(conn), swConnection_get_port(conn), package_length);
                return SW_ERR;
            }
            //get length success
            else
            {
                if (buffer->size < package_length)
                {
                    if (swString_extend(buffer, package_length) < 0)
                    {
                        return SW_ERR;
                    }
                }
                conn->recv_wait = 1;
                buffer->offset = package_length;

                if (buffer->length >= package_length)
                {
                    goto do_dispatch;
                }
                else
                {
                    goto do_recv;
                }
            }
        }
    }
    return SW_OK;
}
Exemple #7
0
/**
 * @return SW_ERR: close the connection
 * @return SW_OK: continue
 */
int swProtocol_recv_check_length(swProtocol *protocol, swConnection *conn, swString *buffer)
{
    int package_length;
    uint8_t package_length_size = protocol->get_package_length_size ? protocol->get_package_length_size(conn) : protocol->package_length_size;
    uint32_t recv_size;

    if (conn->skip_recv)
    {
        conn->skip_recv = 0;
        goto do_get_length;
    }

    do_recv:
	if (conn->active == 0)
	{
		return SW_OK;
	}
    if (buffer->offset > 0)
    {
        recv_size = buffer->offset - buffer->length;
    }
    else
    {
        recv_size = protocol->package_length_offset + package_length_size;
    }

    int n = swConnection_recv(conn, buffer->str + buffer->length, recv_size, 0);
    if (n < 0)
    {
        switch (swConnection_error(errno))
        {
        case SW_ERROR:
            swSysError("recv(%d, %d) failed.", conn->fd, recv_size);
            return SW_OK;
        case SW_CLOSE:
            conn->close_errno = errno;
            return SW_ERR;
        default:
            return SW_OK;
        }
    }
    else if (n == 0)
    {
        return SW_ERR;
    }
    else
    {
        buffer->length += n;

        if (conn->recv_wait)
        {
            if (buffer->length >= buffer->offset)
            {
                do_dispatch:
                if (protocol->onPackage(conn, buffer->str, buffer->offset) < 0)
                {
                    return SW_ERR;
                }
                if (conn->removed)
                {
                    return SW_OK;
                }
                conn->recv_wait = 0;

                int remaining_length = buffer->length - buffer->offset;
                if (remaining_length > 0)
                {
                    memmove(buffer->str, buffer->str + buffer->offset, remaining_length);
                    buffer->offset = 0;
                    buffer->length = remaining_length;
                    goto do_get_length;
                }
                else
                {
                    swString_clear(buffer);
#ifdef SW_USE_OPENSSL
                    if (conn->ssl)
                    {
                        goto do_recv;
                    }
#endif
                }
            }
            return SW_OK;
        }
        else
        {
            do_get_length: package_length = protocol->get_package_length(protocol, conn, buffer->str, buffer->length);
            //invalid package, close connection.
            if (package_length < 0)
            {
                return SW_ERR;
            }
            //no length
            else if (package_length == 0)
            {
                return SW_OK;
            }
            else if (package_length > protocol->package_max_length)
            {
                swWarn("package is too big, remote_addr=%s:%d, length=%d.", swConnection_get_ip(conn), swConnection_get_port(conn), package_length);
                return SW_ERR;
            }
            //get length success
            else
            {
                if (buffer->size < package_length)
                {
                    if (swString_extend(buffer, package_length) < 0)
                    {
                        return SW_ERR;
                    }
                }
                conn->recv_wait = 1;
                buffer->offset = package_length;

                if (buffer->length >= package_length)
                {
                    goto do_dispatch;
                }
                else
                {
                    goto do_recv;
                }
            }
        }
    }
    return SW_OK;
}
Exemple #8
0
/**
 * @return SW_ERR: close the connection
 * @return SW_OK: continue
 */
int swProtocol_recv_check_length(swProtocol *protocol, swConnection *conn, swString *buffer)
{
    char *recvbuf;
    int ret;
    uint32_t recvbuf_size;

    do_recv: recvbuf = buffer->str + buffer->length;
    recvbuf_size = buffer->offset > 0 ? buffer->offset - buffer->length : protocol->package_length_offset + protocol->package_length_size;

    int n = swConnection_recv(conn, recvbuf, recvbuf_size, 0);
    if (n < 0)
    {
        switch (swConnection_error(errno))
        {
        case SW_ERROR:
            swSysError("recv(%d, %p, %d) failed.", conn->fd, recvbuf, recvbuf_size);
            return SW_OK;
        case SW_CLOSE:
            return SW_ERR;
        default:
            return SW_OK;
        }
    }
    else if (n == 0)
    {
        return SW_ERR;
    }
    else
    {
        buffer->length += n;

        if (conn->recv_wait)
        {
            if (buffer->length == buffer->offset)
            {
                do_package: ret = protocol->onPackage(conn, buffer->str, buffer->length);
                conn->recv_wait = 0;
                swString_clear(buffer);
                return ret;
            }
            else
            {
                return SW_OK;
            }
        }
        else
        {
            int package_length = protocol->get_package_length(protocol, conn, buffer->str, buffer->length);
            //invalid package, close connection.
            if (package_length < 0)
            {
                return SW_ERR;
            }
            //no length
            else if (package_length == 0)
            {
                return SW_OK;
            }
            else if (package_length > protocol->package_max_length)
            {
                swWarn("package is too big, remote_addr=%s:%d, length=%d.", swConnection_get_ip(conn), swConnection_get_port(conn), package_length);
                return SW_ERR;
            }
            //get length success
            else
            {
                if (buffer->size < package_length)
                {
                    if (swString_extend(buffer, package_length) < 0)
                    {
                        return SW_ERR;
                    }
                }
                conn->recv_wait = 1;
                buffer->offset = package_length;
                if (buffer->length == package_length)
                {
                    goto do_package;
                }
                else
                {
                    goto do_recv;
                }
            }
        }
    }
    return SW_OK;
}