Ejemplo n.º 1
0
void C4Network2IO::SendConnPackets()
{
    CStdLock ConnListLock(&ConnListCSec);

    // exlusive conn?
    if (fExclusiveConn)
        // find a live connection
        for (C4Network2IOConnection *pConn = pConnList; pConn; pConn = pConn->pNext)
            if (pConn->isAccepted() || (!pConn->isClosed() && pConn->isConnSent()))
                // do not sent additional conn packets - no other connection should succeed
                return;

    // sent pending welcome packet(s)
    for (C4Network2IOConnection *pConn = pConnList; pConn; pConn = pConn->pNext)
        if (pConn->isOpen() && !pConn->isConnSent())
        {
            // make packet
            CStdLock LCCoreLock(&LCCoreCSec);
            C4NetIOPacket Pkt = MkC4NetIOPacket(PID_Conn, C4PacketConn(LCCore, pConn->getID(), pConn->getPassword()));
            LCCoreLock.Clear();
            // send
            if (!pConn->Send(Pkt))
                pConn->Close();
            else
            {
                // set flag
                pConn->SetConnSent();
                // only one conn packet at a time
                if (fExclusiveConn)
                    return;
            }
        }

}
Ejemplo n.º 2
0
void C4Network2IO::HandleFwdReq(const C4PacketFwd &rFwd, C4Network2IOConnection *pBy)
{
    CStdLock ConnListLock(&ConnListCSec);
    // init packet
    C4PacketFwd nFwd;
    nFwd.SetListType(false);
    // find all clients the message should be forwarded to
    int iClientID;
    C4Network2IOConnection *pConn;
    for (pConn = pConnList; pConn; pConn = pConn->pNext)
        if (pConn->isAccepted())
            if ((iClientID = pConn->getClientID()) >= 0)
                if (iClientID != pBy->getClientID())
                    if (rFwd.DoFwdTo(iClientID) && !nFwd.DoFwdTo(iClientID))
                        nFwd.AddClient(iClientID);
    // check count (hardcoded: broadcast for > 2 clients)
    if (nFwd.getClientCnt() <= 2)
    {
        C4NetIOPacket Pkt(rFwd.getData(), C4NetIO::addr_t());
        for (int i = 0; i < nFwd.getClientCnt(); i++)
            if ((pConn = GetMsgConnection(nFwd.getClient(i))))
            {
                pConn->Send(Pkt);
                pConn->DelRef();
            }
    }
    else
    {
        // Temporarily unlock connection list for getting broadcast lock
        // (might lead to deathlocks otherwise, as the lock is often taken
        //  in the opposite order)
        ConnListLock.Clear();

        BeginBroadcast();
        nFwd.SetData(rFwd.getData());
        // add all clients
        CStdLock ConnListLock(&ConnListCSec);
        for (int i = 0; i < nFwd.getClientCnt(); i++)
            if ((pConn = GetMsgConnection(nFwd.getClient(i))))
            {
                pConn->SetBroadcastTarget(true);
                pConn->DelRef();
            }
        // broadcast
        Broadcast(MkC4NetIOPacket(PID_Fwd, nFwd));
        EndBroadcast();
    }
    // doing a callback here; don't lock!
    ConnListLock.Clear();
    // forward to self?
    if (rFwd.DoFwdTo(LCCore.getID()))
    {
        C4NetIOPacket Packet(rFwd.getData(), pBy->getPeerAddr());
        HandlePacket(Packet, pBy, true);
    }
}
Ejemplo n.º 3
0
bool C4Network2IO::SendMsgToClient(C4NetIOPacket &rPkt, int iClient) // by both
{
    // find msg connection
    C4Network2IOConnection *pConn = GetMsgConnection(iClient);
    if (!pConn) return false;
    // send
    bool fSuccess = pConn->Send(rPkt);
    pConn->DelRef();
    return fSuccess;
}
Ejemplo n.º 4
0
bool C4Network2IO::Broadcast(const C4NetIOPacket &rPkt)
{
    bool fSuccess = true;
    // There is no broadcasting atm, emulate it
    CStdLock ConnListLock(&ConnListCSec);
    for (C4Network2IOConnection *pConn = pConnList; pConn; pConn = pConn->pNext)
        if (pConn->isOpen() && pConn->isBroadcastTarget())
            fSuccess &= pConn->Send(rPkt);
    if(!fSuccess)
        Log("Network: Warning! Broadcast failed.");
    return fSuccess;
}
Ejemplo n.º 5
0
void C4Network2Client::CloseConns(const char *szMsg) {
  C4PacketConnRe Pkt(false, false, szMsg);
  C4Network2IOConnection *pConn;
  while (pConn = pMsgConn) {
    // send packet, close
    if (pConn->isOpen()) {
      pConn->Send(MkC4NetIOPacket(PID_ConnRe, Pkt));
      pConn->Close();
    }
    // remove
    RemoveConn(pConn);
  }
}
Ejemplo n.º 6
0
bool C4Network2IO::Ping()
{
    bool fSuccess = true;
    // ping all connections
    for (C4Network2IOConnection *pConn = pConnList; pConn; pConn = pConn->pNext)
        if (pConn->isOpen())
        {
            C4PacketPing Ping(pConn->getInPacketCounter(), pConn->getOutPacketCounter());
            fSuccess &= pConn->Send(MkC4NetIOPacket(PID_Ping, Ping));
            pConn->OnPing();
        }
    return fSuccess;
}
Ejemplo n.º 7
0
bool C4Network2Res::SendChunk(uint32_t iChunk, int32_t iToClient)
{
	assert(pParent && pParent->getIOClass());
	if (!szStandalone[0] || iChunk >= Core.getChunkCnt()) return false;
	// find connection for given client (one of the rare uses of the data connection)
	C4Network2IOConnection *pConn = pParent->getIOClass()->GetDataConnection(iToClient);
	if (!pConn) return false;
	// save last request time
	iLastReqTime = time(NULL);
	// create packet
	CStdLock FileLock(&FileCSec);
	C4Network2ResChunk ResChunk;
	ResChunk.Set(this, iChunk);
	// send
	bool fSuccess = pConn->Send(MkC4NetIOPacket(PID_NetResData, ResChunk));
	pConn->DelRef();
	return fSuccess;
}
Ejemplo n.º 8
0
bool C4Network2Res::StartLoad(int32_t iFromClient, const C4Network2ResChunkData &Available)
{
	assert(pParent && pParent->getIOClass());
	// all slots used? ignore
	if (iLoadCnt + 1 >= C4NetResMaxLoad) return true;
	// is there already a load by this client? ignore
	for (C4Network2ResLoad *pPos = pLoads; pPos; pPos = pPos->Next())
		if (pPos->getByClient() == iFromClient)
			return true;
	// find chunk to retrieve
	int32_t iLoads[C4NetResMaxLoad]; int32_t i = 0;
	for (C4Network2ResLoad *pLoad = pLoads; pLoad; pLoad = pLoad->Next())
		iLoads[i++] = pLoad->getChunk();
	int32_t iRetrieveChunk = Chunks.GetChunkToRetrieve(Available, i, iLoads);
	// nothing? ignore
	if (iRetrieveChunk < 0 || (uint32_t)iRetrieveChunk >= Core.getChunkCnt())
		return true;
	// search message connection for client
	C4Network2IOConnection *pConn = pParent->getIOClass()->GetMsgConnection(iFromClient);
	if (!pConn) return false;
	// send request
	if (!pConn->Send(MkC4NetIOPacket(PID_NetResReq, C4PacketResRequest(Core.getID(), iRetrieveChunk))))
		{ pConn->DelRef(); return false; }
	pConn->DelRef();
#ifdef C4NET2RES_DEBUG_LOG
	// log
	Application.InteractiveThread.ThreadLogS("Network: Res: requesting chunk %d of %d:%s (%s) from client %d",
	    iRetrieveChunk, Core.getID(), Core.getFileName(), szFile, iFromClient);
#endif
	// create load class
	C4Network2ResLoad *pnLoad = new C4Network2ResLoad(iRetrieveChunk, iFromClient);
	// add to list
	pnLoad->pNext = pLoads;
	pLoads = pnLoad;
	iLoadCnt++;
	// ok
	return true;
}