void C4Network2IO::OnDisconn(const C4NetIO::addr_t &addr, C4NetIO *pNetIO, const char *szReason) { // punch? if (pNetIO == pNetIO_UDP) if (PuncherAddr.sin_addr.s_addr && AddrEqual(PuncherAddr, addr)) { ZeroMem(&PuncherAddr, sizeof(PuncherAddr)); return; } #if(C4NET2IO_DUMP_LEVEL > 1) Application.InteractiveThread.ThreadLogS("OnDisconn: %s %s", C4TimeMilliseconds::Now().AsString().getData(), getNetIOName(pNetIO)); #endif // find connection C4Network2IOConnection *pConn = GetConnection(addr, pNetIO); if (!pConn) pConn = GetConnectionByConnAddr(addr, pNetIO); if (!pConn) return; #if(C4NET2IO_DUMP_LEVEL > 0) // log Application.InteractiveThread.ThreadLogS("Network: %s connection to %s:%d %s (%s)", getNetIOName(pNetIO), inet_ntoa(addr.sin_addr), htons(addr.sin_port), pConn->isConnecting() ? "failed" : "closed" , szReason); #endif // already closed? ignore if (!pConn->isClosed()) // not accepted yet? count as connection failure pConn->SetStatus(pConn->isHalfAccepted() ? CS_Closed : CS_ConnectFail); // keep connection for main thread message pConn->AddRef(); // check for pending welcome packets SendConnPackets(); // signal to main thread Application.InteractiveThread.PushEvent(Ev_Net_Disconn, pConn); // don't remove connection from list - wait for postmortem or timeout }
// C4NetIO interface bool C4Network2IO::OnConn(const C4NetIO::addr_t &PeerAddr, const C4NetIO::addr_t &ConnectAddr, const C4NetIO::addr_t *pOwnAddr, C4NetIO *pNetIO) { // puncher answer? We just make sure here a connection /can/ be established, so close it instantly. if (pNetIO == pNetIO_UDP) if (PuncherAddr.sin_addr.s_addr && AddrEqual(PuncherAddr, ConnectAddr)) { // got an address? if (pOwnAddr) OnPunch(*pOwnAddr); // this is only a test connection - close it instantly return false; } #if(C4NET2IO_DUMP_LEVEL > 1) Application.InteractiveThread.ThreadLogS("OnConn: %s %s", C4TimeMilliseconds::Now().AsString().getData(), getNetIOName(pNetIO)); #endif // search connection C4Network2IOConnection *pConn = NULL; if (ConnectAddr.sin_addr.s_addr) pConn = GetConnectionByConnAddr(ConnectAddr, pNetIO); // not found? if (!pConn) { // allow connect? if (!fAllowConnect) return false; // create new connection object uint32_t iConnID = iNextConnID++; pConn = new C4Network2IOConnection(); pConn->Set(pNetIO, getNetIOProt(pNetIO), PeerAddr, ConnectAddr, CS_Connected, NULL, iConnID); // add to list AddConnection(pConn); } else { // already closed this connection (attempt)? if (pConn->isClosed()) return false; if (!pConn->isOpen()) { // change status pConn->SetStatus(CS_Connected); pConn->SetPeerAddr(PeerAddr); } } // send welcome packet, if appropriate SendConnPackets(); #if(C4NET2IO_DUMP_LEVEL > 0) // log Application.InteractiveThread.ThreadLogS("Network: got %s connection from %s:%d", getNetIOName(pNetIO), inet_ntoa(PeerAddr.sin_addr), htons(PeerAddr.sin_port)); #endif // do event (disabled - unused) // pConn->AddRef(); PushNetEv(NE_Conn, pConn); // ok return true; }