Пример #1
0
void WebSocketImpl::onClose(int err)
{
    KUMA_INFOXTRACE("onClose, err="<<err);
    cleanup();
    setState(STATE_CLOSED);
    if(cb_error_) cb_error_(KUMA_ERROR_SOCKERR);
}
Пример #2
0
void TcpSocketImpl::onClose(int err)
{
    KUMA_INFOXTRACE("onClose, err="<<err<<", state="<<getState());
    cleanup();
    setState(ST_CLOSED);
    if(cb_error_) cb_error_(err);
}
Пример #3
0
int WebSocketImpl::close()
{
    KUMA_INFOXTRACE("close");
    cleanup();
    setState(STATE_CLOSED);
    return KUMA_ERROR_NOERR;
}
Пример #4
0
int TcpSocketImpl::attachFd(SOCKET_FD fd, SSL* ssl, uint32_t flags)
{
    KUMA_INFOXTRACE("attachFd, with ssl, fd="<<fd<<", flags="<<flags<<", state="<<getState());
    if(getState() != ST_IDLE) {
        KUMA_ERRXTRACE("attachFd, invalid state, state="<<getState());
        return KUMA_ERROR_INVALID_STATE;
    }
    
    fd_ = fd;
    flags_ = flags;
    setSocketOption();
    setState(ST_OPEN);
    
    if(SslEnabled()) {
        if (ssl) {
            ssl_handler_ = new SslHandler();
            ssl_handler_->attachSsl(ssl);
        } else {
            int ret = startSslHandshake(true);
            if(ret != KUMA_ERROR_NOERR) {
                return ret;
            }
        }
    }

    loop_->registerFd(fd_, KUMA_EV_NETWORK, [this] (uint32_t ev) { ioReady(ev); });
    registered_ = true;
    return KUMA_ERROR_NOERR;
}
Пример #5
0
int TcpSocketImpl::startSslHandshake(bool is_server)
{
#ifdef KUMA_HAS_OPENSSL
    KUMA_INFOXTRACE("startSslHandshake, is_server="<<is_server<<", fd="<<fd_<<", state="<<getState());
    if(INVALID_FD == fd_) {
        KUMA_ERRXTRACE("startSslHandshake, invalid fd");
        return KUMA_ERROR_INVALID_STATE;
    }
    if(ssl_handler_) {
        ssl_handler_->close();
        delete ssl_handler_;
        ssl_handler_ = nullptr;
    }
    ssl_handler_ = new SslHandler();
    int ret = ssl_handler_->attachFd(fd_, is_server);
    if(ret != KUMA_ERROR_NOERR) {
        return ret;
    }
    flags_ |= FLAG_HAS_SSL;
    SslHandler::SslState ssl_state = ssl_handler_->doSslHandshake();
    if(SslHandler::SslState::SSL_ERROR == ssl_state) {
        return KUMA_ERROR_SSL_FAILED;
    }
    return KUMA_ERROR_NOERR;
#else
    return KUMA_ERROR_UNSUPPORT;
#endif
}
Пример #6
0
int TcpSocketImpl::attachFd(SOCKET_FD fd, uint32_t flags)
{
    KUMA_INFOXTRACE("attachFd, fd="<<fd<<", flags="<<flags<<", state="<<getState());
    if(getState() != ST_IDLE) {
        KUMA_ERRXTRACE("attachFd, invalid state, state="<<getState());
        return KUMA_ERROR_INVALID_STATE;
    }
    flags_ = flags;
#ifndef KUMA_HAS_OPENSSL
    if (SslEnabled()) {
        KUMA_ERRXTRACE("attachFd, OpenSSL is disabled");
        return KUMA_ERROR_UNSUPPORT;
    }
#endif
    
    fd_ = fd;
    setSocketOption();
    setState(ST_OPEN);
#ifdef KUMA_HAS_OPENSSL
    if(SslEnabled()) {
        int ret = startSslHandshake(true);
        if(ret != KUMA_ERROR_NOERR) {
            return ret;
        }
    }
#endif
    loop_->registerFd(fd_, KUMA_EV_NETWORK, [this] (uint32_t ev) { ioReady(ev); });
    registered_ = true;
    return KUMA_ERROR_NOERR;
}
Пример #7
0
int TcpSocketImpl::close()
{
    KUMA_INFOXTRACE("close, state="<<getState());
    loop_->runInEventLoopSync([this] {
        cleanup();
        setState(ST_CLOSED);
    });
    return KUMA_ERROR_NOERR;
}
Пример #8
0
void WebSocketImpl::onStateOpen()
{
    KUMA_INFOXTRACE("onStateOpen");
    setState(STATE_OPEN);
    if(is_server_) {
        if(cb_write_) cb_write_(0);
    } else {
        if(cb_connect_) cb_connect_(0);
    }
}
Пример #9
0
int TcpSocketImpl::detachFd(SOCKET_FD &fd)
{
    KUMA_INFOXTRACE("detachFd, fd="<<fd_<<", state="<<getState());
    fd = fd_;
    fd_ = INVALID_FD;
    if(registered_) {
        registered_ = false;
        loop_->unregisterFd(fd, false);
    }
    cleanup();
    setState(ST_CLOSED);
    return KUMA_ERROR_NOERR;
}
Пример #10
0
void TcpSocketImpl::onConnect(int err)
{
    KUMA_INFOXTRACE("onConnect, err="<<err<<", state="<<getState());
    if(0 == err) {
        setState(ST_OPEN);
#ifdef KUMA_HAS_OPENSSL
        if(SslEnabled()) {
            err = startSslHandshake(false);
            if(KUMA_ERROR_NOERR == err && ssl_handler_->getState() == SslHandler::SslState::SSL_HANDSHAKE) {
                return; // continue to SSL handshake
            }
        }
#endif
    }
    if(err != KUMA_ERROR_NOERR) {
        cleanup();
        setState(ST_CLOSED);
    }
    EventCallback cb_connect = std::move(cb_connect_);
    if(cb_connect) cb_connect(err);
}
Пример #11
0
void EventLoop::Impl::loop(uint32_t max_wait_ms)
{
    while (!stop_loop_) {
        loopOnce(max_wait_ms);
    }
    processTasks();
    
    while (pending_objects_) {
        auto obj = pending_objects_;
        pending_objects_ = pending_objects_->next_;
        obj->onLoopExit();
    }
    {
        LockGuard g(obs_mutex_);
        ObserverCallback cb;
        while (obs_queue_.dequeue(cb)) {
            cb(LoopActivity::EXIT);
        }
    }
    KUMA_INFOXTRACE("loop, stopped");
}
Пример #12
0
int TcpSocketImpl::connect_i(const char* host, uint16_t port, uint32_t timeout)
{
    KUMA_INFOXTRACE("connect_i, host="<<host<<", port="<<port<<", this="<<this);
#ifndef KUMA_HAS_OPENSSL
    if (SslEnabled()) {
        KUMA_ERRXTRACE("connect_i, OpenSSL is disabled");
        return KUMA_ERROR_UNSUPPORT;
    }
#endif
    sockaddr_storage ss_addr = {0};
    struct addrinfo hints = {0};
    hints.ai_family = AF_UNSPEC;
    hints.ai_flags = AI_ADDRCONFIG; // will block 10 seconds in some case if not set AI_ADDRCONFIG
    if(km_set_sock_addr(host, port, &hints, (struct sockaddr*)&ss_addr, sizeof(ss_addr)) != 0) {
        return KUMA_ERROR_INVALID_PARAM;
    }
    if(INVALID_FD == fd_) {
        fd_ = ::socket(ss_addr.ss_family, SOCK_STREAM, 0);
        if(INVALID_FD == fd_) {
            KUMA_ERRXTRACE("connect_i, socket failed, err="<<getLastError());
            return KUMA_ERROR_FAILED;
        }
    }
    setSocketOption();
    
    int addr_len = sizeof(ss_addr);
#ifdef KUMA_OS_MAC
    if(AF_INET == ss_addr.ss_family)
        addr_len = sizeof(sockaddr_in);
    else
        addr_len = sizeof(sockaddr_in6);
#endif
    int ret = ::connect(fd_, (struct sockaddr *)&ss_addr, addr_len);
    if(0 == ret) {
        setState(ST_CONNECTING); // wait for writable event
    } else if(ret < 0 &&
#ifdef KUMA_OS_WIN
              WSAEWOULDBLOCK
#else
              EINPROGRESS
#endif
              == getLastError()) {
        setState(ST_CONNECTING);
    } else {
        KUMA_ERRXTRACE("connect_i, error, fd="<<fd_<<", err="<<getLastError());
        cleanup();
        setState(ST_CLOSED);
        return KUMA_ERROR_FAILED;
    }
#if defined(KUMA_OS_LINUX) || defined(KUMA_OS_MAC)
    socklen_t len = sizeof(ss_addr);
#else
    int len = sizeof(ss_addr);
#endif
    char local_ip[128] = {0};
    uint16_t local_port = 0;
    ret = getsockname(fd_, (struct sockaddr*)&ss_addr, &len);
    if(ret != -1) {
        km_get_sock_addr((struct sockaddr*)&ss_addr, sizeof(ss_addr), local_ip, sizeof(local_ip), &local_port);
    }
    
    KUMA_INFOXTRACE("connect_i, fd="<<fd_<<", local_ip="<<local_ip
                   <<", local_port="<<local_port<<", state="<<getState());
    
    loop_->registerFd(fd_, KUMA_EV_NETWORK, [this] (uint32_t ev) { ioReady(ev); });
    registered_ = true;
    return KUMA_ERROR_NOERR;
}
Пример #13
0
void EventLoop::Impl::stop()
{
    KUMA_INFOXTRACE("stop");
    stop_loop_ = true;
    poll_->notify();
}