Exemple #1
0
void Tunnelc::onENetPeerConnected(ENetHost *enhost, ENetPeer *enpeer, quint32 data)
{
    qDebug()<<enhost<<enpeer<<data;
    // ToxTunChannel *chan = this->m_enpeer_chans[enpeer];
    // ToxTunChannel *chan = (ToxTunChannel*)enpeer->toxchan;
    ToxTunChannel *chan = peerLastChan(enpeer);
    // enet_peer_ping_interval()
    // enet_peer_ping(
    enet_peer_timeout(enpeer, UINT32_MAX/*ENET_PEER_TIMEOUT_LIMIT * 0xfffff*/,
                      UINT32_MAX/*ENET_PEER_TIMEOUT_MINIMUM * 0xffff*/,
                      UINT32_MAX/*ENET_PEER_TIMEOUT_MAXIMUM * 0xffff*/);
    enet_peer_ping_interval(enpeer, UINT32_MAX/*ENET_PEER_PING_INTERVAL * 0xfffff*/);
    
    emit chan->m_sock->readyRead();

    if (false) {
        ENetPacket *packet = enet_packet_create("hehehe123", 10, ENET_PACKET_FLAG_RELIABLE);

        enet_packet_resize(packet, 13);
        strcpy((char*)&packet->data[9], "foo");
    
        uint8_t chanid = 0;
        // enet_peer_send(enpeer, chanid, packet);
        m_enpoll->sendPacket(enpeer, chanid, packet);
    }
}
Exemple #2
0
void CNetServerSession::SetLocalClient(bool isLocalClient)
{
	m_IsLocalClient = isLocalClient;

	if (!isLocalClient)
		return;

	// Prevent the local client of the host from timing out too quickly
#if (ENET_VERSION >= ENET_VERSION_CREATE(1, 3, 4))
	enet_peer_timeout(m_Peer, 0, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT);
#endif
}
void NetClient::Connect(const char* connect)
{
	m_enetclient = enet_host_create(NULL, 1, 1, 350000, 95000); // This is 3 megabit d/l, .75 megabit upload. Should be the lowest common denominator of internet connection today.

	ENetAddress address;
	enet_address_set_host(&address, connect);
	address.port = 51072;

	m_enetpeer = enet_host_connect(m_enetclient, &address, 1, 0);

#ifdef _DEBUG
	enet_peer_timeout(m_enetpeer, UINT32_MAX, UINT32_MAX, UINT32_MAX);
#endif
}
//Connect to a server
bool Network::connect(const ENetAddress & addr)
{
	if (m_connecting)
		return false;
	disconnect();

	m_server = enet_host_connect(m_client, &addr, 2, 0);

	if (!m_server)
		return false;
	enet_peer_timeout(m_server, ENET_PEER_TIMEOUT_LIMIT, 500, 3000);
	m_connecting = true;
	return true;
}
Exemple #5
0
bool Client::connect(const char* address, unsigned int port)
{
    m_client = enet_host_create(nullptr /* create a client host */,
                                1 /* only allow 1 outgoing connection */,
                                2 /* allow up 2 channels to be used, 0 and 1 */,
                                57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
                                14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);

    Debug::assertf(m_client, "failed to create ENet client host");

    enet_address_set_host(&m_address, address);
    m_address.port = port;

    m_peer = enet_host_connect(m_client, &m_address, 2, 0);

    if (Settings::instance()->startupFlags() & Settings::NoTimeoutStartupFlag) {
        enet_peer_timeout(m_peer, 0, 3600 * 1000, 3600 * 1000);
    }

    if (m_peer == NULL) {
        Debug::log(Debug::Area::NetworkClientInitialArea) << "Client failed to connect to server";
        exit(EXIT_FAILURE);
    }

    ENetEvent event;
    if (enet_host_service(m_client, &event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) {
        Debug::log(Debug::Area::NetworkClientInitialArea) << "Client connection to server succeeded!";
        m_mainMenu->hideMainMenu();

        m_chat = new ChatDialog(this, m_mainMenu);
        m_chat->show();

        //NOTE: no world is created yet. we now wait for the server to receive our initial connection data, and give us back a
        //player id, which we then create as the main player and finally, create the world.
        m_connected = true;
        sendInitialConnectionData();
        return true;
    } else {
        Debug::log(Debug::Area::NetworkClientInitialArea) << "Client connection to server failed!";
        Debug::log(Debug::Area::NetworkClientInitialArea) << "Client failed to connect to server within timeout";
        enet_peer_reset(m_peer);
        return false;
    }
}
Exemple #6
0
    Client::Client()
    {
        mAddress.port = 6666;

        enet_address_set_host(&mAddress, "127.0.0.1");
        mHost = enet_host_create(NULL, 32, 2, 0, 0);
        mServerPeer = enet_host_connect(mHost, &mAddress, 2, 0);
        enet_peer_timeout(mServerPeer, std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::max());

        ENetEvent event;

        if (enet_host_service(mHost, &event, 5000))
        {
            std::cout << "connected" << std::endl;
        }
        else
        {
            std::cout << "connection failed" << std::endl;
        }
    }
Exemple #7
0
bool CNetClientSession::Connect(const CStr& server, const u16 port, const bool isLocalClient)
{
	ENSURE(!m_Host);
	ENSURE(!m_Server);

	// Create ENet host
	ENetHost* host = enet_host_create(NULL, 1, CHANNEL_COUNT, 0, 0);
	if (!host)
		return false;

	// Bind to specified host
	ENetAddress addr;
	addr.port = port;
	if (enet_address_set_host(&addr, server.c_str()) < 0)
		return false;

	// Initiate connection to server
	ENetPeer* peer = enet_host_connect(host, &addr, CHANNEL_COUNT, 0);
	if (!peer)
		return false;

	m_Host = host;
	m_Server = peer;

	// Prevent the local client of the host from timing out too quickly.
#if (ENET_VERSION >= ENET_VERSION_CREATE(1, 3, 4))
	if (isLocalClient)
		enet_peer_timeout(peer, 1, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT);
#endif

	m_Stats = new CNetStatsTable(m_Server);
	if (CProfileViewer::IsInitialised())
		g_ProfileViewer.AddRootTable(m_Stats);

	return true;
}
Exemple #8
0
void Tunneld::promiseChannelCleanup(ToxTunChannel *chan)
{
    qDebug()<<chan<<sender();
    QObject *snderobj = (QObject*)sender();
    QTimer *repeat_timer = NULL;

    qDebug()<<snderobj->objectName()<<snderobj->metaObject()->className();
    if (chan == NULL) {
        repeat_timer = (QTimer*)snderobj;
        assert(repeat_timer != NULL);
        int conid = repeat_timer->property("conid").toInt();
        if (!m_conid_chans.contains(conid)) {
            qDebug()<<"maybe too late repeat check self sock close timer event";
            repeat_timer->deleteLater();
            return;
        }
        chan = m_conid_chans[conid];
        assert(chan != NULL);
    } else {
        // snderobj is ENetPoll or QTcpSocket
    }
    QTcpSocket *sock = chan->m_sock;
    ENetPeer *enpeer = chan->m_enpeer;

    //////////
    QHash<QString, bool> promise_results;

    promise_results["sock_closed"] = chan->sock_closed;
    // promise_results["enet_closed"] = chan->enet_closed;
    promise_results["peer_sock_closed"] = chan->peer_sock_closed;

    bool promise_result = true;
    for (auto it = promise_results.begin(); it != promise_results.end(); it ++) {
        QString key = it.key();
        bool val = it.value();
        promise_result = promise_result && val;
    }

    if (true) {
        // 检测对方最近的回包情况
        if (!promise_result && repeat_timer == NULL
            && promise_results["peer_sock_closed"] && !promise_results["sock_closed"]) {
            qDebug()<<"here";
            if (chan->last_recv_peer_pkt_time == QDateTime()) {
                qDebug()<<"maybe can close socket right now, because recv nothing forever";
            }
            
            QTimer *t = new QTimer();
            t->setInterval(500);
            t->setSingleShot(true);
            t->setProperty("conid", QVariant(chan->m_conid));
            // // QObject::connect(t, &QTimer::timeout, this, &Tunneld::promiseChannelCleanup, Qt::QueuedConnection);
            QObject::connect(t, SIGNAL(timeout()), this, SLOT(promiseChannelCleanup()), Qt::QueuedConnection);
            qDebug()<<"start repeat check sock close timer:";
            t->start();
        }
        if (!promise_result && repeat_timer != NULL
            && promise_results["peer_sock_closed"] && !promise_results["sock_closed"]) {
            //
            QDateTime now_time = QDateTime::currentDateTime();
            uint32_t last_recv_to_now_time = chan->last_recv_peer_pkt_time.msecsTo(now_time);
            qDebug()<<"here:"<<last_recv_to_now_time<<enpeer->lastReceiveTime;
            if (last_recv_to_now_time > 7000) {
                qDebug()<<"last recv to now, force close self socket:"<<last_recv_to_now_time
                        <<enpeer->incomingPeerID<<enpeer->outgoingPeerID;
                // 不能直接关闭,要在当前函数执行完后,即下一次事件的时候开始执行。
                QTimer::singleShot(1, sock, &QTcpSocket::close);
                // QTimer *t = new QTimer();
                // t->setSingleShot(true);
                // QObject::connect(t, &QTimer::timeout, sock, &QTcpSocket::close, Qt::QueuedConnection);
                // t->start(1);
                
                repeat_timer->deleteLater();
            } else {
                repeat_timer->start();
            }
        }
    }
    
    if (!promise_result) {
        qDebug()<<"promise nooooot satisfied:"<<promise_results<<chan->m_conid;
        return;
    }
    
    chan->promise_close_time = QDateTime::currentDateTime();
    qDebug()<<"promise satisfied."<<chan->m_conid;

    ///// do cleanup
    bool force_closed = chan->force_closed;
    
    // enpeer->toxchan = NULL;  // cleanup
    peerRemoveChan(enpeer, chan);
    
    this->m_sock_chans.remove(sock);
    // this->m_enpeer_chans.remove(enpeer);
    this->m_conid_chans.remove(chan->m_conid);

    delete chan;
    sock->disconnect();
    sock->deleteLater();
    if (repeat_timer != NULL) repeat_timer->deleteLater();
    qDebug()<<"curr chan size:"<<this->m_sock_chans.count()<<this->m_conid_chans.count();

    if (force_closed) {
        return;
    }

    // 延时关闭enet_peer
    QTimer *t = new QTimer();
    auto later_close_timeout = [enpeer, t]() {
        qDebug()<<enpeer<<enpeer->state;
        if (enpeer->state != ENET_PEER_STATE_CONNECTED) {
            qDebug()<<"warning, peer currently not connected:"<<enpeer->incomingPeerID;
        }

        if (! (enet_list_empty (& enpeer -> outgoingReliableCommands) &&
               enet_list_empty (& enpeer -> outgoingUnreliableCommands) && 
               enet_list_empty (& enpeer -> sentReliableCommands))) {
            qDebug()<<"warning, maybe has unsent packet:"<<enpeer->incomingPeerID;
        }

        qDebug()<<"last recv time:"<<enpeer->incomingPeerID
        <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get());

        qDebug()<<"restore peer timeout, ping interval";
        enet_peer_timeout(enpeer, ENET_PEER_TIMEOUT_LIMIT*2,
                          ENET_PEER_TIMEOUT_MINIMUM*2, ENET_PEER_TIMEOUT_MAXIMUM*2);
        enet_peer_ping_interval(enpeer, ENET_PEER_PING_INTERVAL*2);

        // enet_peer_disconnect_now(enpeer, qrand());
        enet_peer_disconnect_later(enpeer, qrand());
        t->deleteLater();
    };

    qDebug()<<"last recv time:"<<enpeer->incomingPeerID
            <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get());
    // QTimer::singleShot(5678, later_close_timeout);
    t->setInterval(5678);
    t->setSingleShot(true);
    QObject::connect(t, &QTimer::timeout, later_close_timeout);
    t->start();
}
Exemple #9
0
void Tunnelc::onNewTcpConnection()
{
    QTcpServer *tcpsrv = (QTcpServer*)sender();
    QTcpSocket *sock = tcpsrv->nextPendingConnection();
    int idx = this->m_tcpsrvs[tcpsrv];
    ToxTunRecord rec = this->m_cfg->m_recs[idx];

    QObject::connect(sock, &QTcpSocket::readyRead, this, &Tunnelc::onTcpReadyRead, Qt::QueuedConnection);
    QObject::connect(sock, &QTcpSocket::disconnected, this, &Tunnelc::onTcpDisconnected, Qt::QueuedConnection);

    //// channels
    QString friendId = "D62E57FCBDC04080C5F78875AB24DB2AE4C797B5C5A9AC69DB5924FD972E363AF2038D5B7A44";
    friendId = rec.m_remote_pubkey;
    ToxTunChannel *chan = new ToxTunChannel();
    chan->m_sock = sock;
    chan->m_enhost = m_encli;
    // chan->m_enpeer = peer;
    chan->m_peer_pubkey = friendId;
    chan->m_host = "127.0.0.1";
    chan->m_port = rec.m_remote_port;
    chan->m_conid = nextConid();

    //
    ENetAddress eaddr = {0};
    enet_address_set_host(&eaddr, "127.0.0.1");  // tunip: 10.0.5.x
    eaddr.port = 7767;

    ENetPeer *peer = enet_host_connect(this->m_encli, &eaddr, 2, chan->m_port);
    if (peer == NULL) {
        qDebug()<<"error: can not connect to enet, maybe exceed max connection:"
                <<m_encli->peerCount<<enet_host_used_peer_size(m_encli);
        // cleanup and close socket
        // sock->disconnect();
        // this->m_sock_chans.remove(sock);
        // sock->close();
    }
    qDebug()<<peer<<peer->connectID
            <<"tol:"<<peer->timeoutLimit<<"tomin:"<<peer->timeoutMinimum
            <<"tomax:"<<peer->timeoutMaximum;
    // peer->timeoutLimit *= 10;
    // peer->timeoutMinimum *= 10;
    // peer->timeoutMaximum *= 10;
    enet_peer_timeout(peer, ENET_PEER_TIMEOUT_LIMIT, ENET_PEER_TIMEOUT_MINIMUM, ENET_PEER_TIMEOUT_MAXIMUM);
    enet_peer_ping_interval(peer, ENET_PEER_PING_INTERVAL);

    if (peerChansCount(peer) > 0) {
        qDebug()<<peer->incomingPeerID;
        ToxTunChannel *tchan = peerLastChan(peer);
        qDebug()<<tchan<<tchan->m_conid
                <<tchan->sock_closed<<tchan->peer_sock_closed<<tchan->enet_closed;
        // promiseChannelCleanup(tchan);
        // 无条件把相关联的chan清理掉
        if (tchan->sock_closed == true && tchan->peer_sock_closed == false) {
            qDebug()<<"need force cleanup:"<<tchan->m_conid;
            tchan->peer_sock_closed = true;
            tchan->force_closed = true;
            promiseChannelCleanup(tchan); 
        }
        else
        if (tchan->sock_closed == false && tchan->peer_sock_closed == false) {
            qDebug()<<"need force cleanup:"<<tchan->m_conid;
            tchan->peer_sock_closed = true;
            tchan->sock_closed = true;
            tchan->force_closed = true;
            promiseChannelCleanup(tchan); 
        }
        assert(peerChansCount(peer) == 0);
        // assert(1 == 2);
    }
    peerAddChan(peer, chan);
    
    chan->m_enpeer = peer;
    this->m_sock_chans[sock] = chan;
    // this->m_enpeer_chans[peer] = chan;
    this->m_conid_chans[chan->m_conid] = chan;
}