bool C4Network2IO::Connect(const C4NetIO::addr_t &addr, C4Network2IOProtocol eProt, const C4ClientCore &nCCore, const char *szPassword) // by main thread { // get network class C4NetIO *pNetIO = getNetIO(eProt); if (!pNetIO) return false; // already connected/connecting? if (GetConnectionByConnAddr(addr, pNetIO)) return true; // assign new connection ID, peer address isn't known yet uint32_t iConnID = iNextConnID++; C4NetIO::addr_t paddr; ZeroMem(&paddr, sizeof paddr); // create connection object and add to list C4Network2IOConnection *pConn = new C4Network2IOConnection(); pConn->Set(pNetIO, eProt, paddr, addr, CS_Connect, szPassword, iConnID); pConn->SetCCore(nCCore); AddConnection(pConn); // connect if (!pConn->Connect()) { // show error LogF("Network: could not connect to %s:%d using %s: %s", inet_ntoa(addr.sin_addr), htons(addr.sin_port), getNetIOName(pNetIO), pNetIO->GetError() ? pNetIO->GetError() : ""); pNetIO->ResetError(); // remove class RemoveConnection(pConn); return false; } // ok, wait for connection return true; }
// 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; }