Ejemplo n.º 1
0
void C4Network2ClientList::HandlePacket(char cStatus,
                                        const C4PacketBase *pBasePkt,
                                        C4Network2IOConnection *pConn) {
  // find associated client
  C4Network2Client *pClient = GetClient(pConn);
  if (!pClient) return;

#define GETPKT(type, name) \
  assert(pBasePkt);        \
  const type &name = /*dynamic_cast*/ static_cast<const type &>(*pBasePkt);

  switch (cStatus) {
    case PID_Addr:  // address propagation
    {
      GETPKT(C4PacketAddr, rPkt)
      // find client
      pClient = GetClientByID(rPkt.getClientID());
      if (pClient) {
        C4Network2Address addr = rPkt.getAddr();
        // IP zero? Set to IP from where the packet came
        if (addr.isIPNull()) addr.SetIP(pConn->getPeerAddr().sin_addr);
        // add (no announce)
        if (pClient->AddAddr(addr, true))
          // new address? Try to connect
          pClient->DoConnectAttempt(pIO);
      }
    } break;
  }

#undef GETPKT
}
Ejemplo n.º 2
0
bool C4Network2Client::DoTCPSimultaneousOpen(class C4Network2IO *pIO, const C4Network2Address &addr)
{
	if (!pIO->getNetIO(P_TCP)) return false;

	// Did we already bind a socket?
	if (TcpSimOpenSocket)
	{
		LogSilentF("Network: connecting client %s on %s with TCP simultaneous open...", getName(), addr.getAddr().ToString().getData());
		return pIO->ConnectWithSocket(addr.getAddr(), addr.getProtocol(), pClient->getCore(), std::move(TcpSimOpenSocket));
	}
	else
	{
		// No - bind one, inform peer, and schedule a connection attempt.
		auto NetIOTCP = dynamic_cast<C4NetIOTCP*>(pIO->getNetIO(P_TCP));
		auto bindAddr = pParent->GetLocal()->IPv6AddrFromPuncher;
		// We need to know an address that works.
		if (bindAddr.IsNull()) return false;
		bindAddr.SetPort(0);
		TcpSimOpenSocket = NetIOTCP->Bind(bindAddr);
		auto boundAddr = TcpSimOpenSocket->GetAddress();
		LogSilentF("Network: %s TCP simultaneous open request for client %s from %s...", addr.isIPNull() ? "initiating" : "responding to",
				getName(), boundAddr.ToString().getData());
		// Send address we bound to to the client.
		if (!SendMsg(MkC4NetIOPacket(PID_TCPSimOpen, C4PacketTCPSimOpen(pParent->GetLocal()->getID(), C4Network2Address(boundAddr, P_TCP)))))
			return false;
		if (!addr.isIPNull())
		{
			// We need to delay the connection attempt a bit. Unfortunately,
			// waiting for the next tick would usually take way too much time.
			// Instead, we block the main thread for a very short time and hope
			// that noone notices...
			int ping = getMsgConn()->getLag();
			std::this_thread::sleep_for(std::chrono::milliseconds(std::min(ping / 2, 10)));
			DoTCPSimultaneousOpen(pIO, addr);
		}
		return true;
	}
}
Ejemplo n.º 3
0
bool C4Network2Address::operator == (const C4Network2Address &addr2) const
{
	return eProtocol == addr2.getProtocol() && AddrEqual(addr, addr2.getAddr());
}
Ejemplo n.º 4
0
void C4Network2ClientDlg::UpdateText()
{
	// begin updating (clears previous text)
	BeginUpdateText();
	// get core
	const C4Client *pClient = Game.Clients.getClientByID(iClientID);
	if (!pClient)
	{
		// client ID unknown
		AddLineFmt(LoadResStr("IDS_NET_CLIENT_INFO_UNKNOWNID"), iClientID);
	}
	else
	{
		// get client (may be nullptr for local info)
		C4Network2Client *pNetClient = pClient->getNetClient();
		// show some info
		StdCopyStrBuf strInfo;
		if (!pClient->isActivated()) { strInfo.Append(LoadResStr("IDS_MSG_INACTIVE")); strInfo.Append(" "); }
		if (pClient->isLocal()) { strInfo.Append(LoadResStr("IDS_MSG_LOCAL")); strInfo.Append(" "); }
		strInfo.AppendFormat("%s %s (ID #%d)%s",
			LoadResStr(pClient->isHost() ? "IDS_MSG_HOST" : "IDS_MSG_CLIENT"),
			pClient->getName(),
			iClientID,
			::Network.isHost() && pNetClient && !pNetClient->isReady() ? " (!ack)" : "");
		AddLine(strInfo.getData());
		// show addresses
		int iCnt;
		if ((iCnt=pNetClient->getAddrCnt()))
		{
			AddLine(LoadResStr("IDS_NET_CLIENT_INFO_ADDRESSES"));
			for (int i=0; i<iCnt; ++i)
			{
				C4Network2Address addr = pNetClient->getAddr(i);
				AddLineFmt("  %d: %s",
				           i,                        // adress index
				           addr.toString().getData());
			}
		}
		else
			AddLine(LoadResStr("IDS_NET_CLIENT_INFO_NOADDRESSES"));
		// show connection
		if (pNetClient)
		{
			// connections
			if (pNetClient->isConnected())
			{
				AddLineFmt(LoadResStr("IDS_NET_CLIENT_INFO_CONNECTIONS"),
				           pNetClient->getMsgConn() == pNetClient->getDataConn() ? "Msg/Data" : "Msg",
				           ::Network.NetIO.getNetIOName(pNetClient->getMsgConn()->getNetClass()),
						   pNetClient->getMsgConn()->getPeerAddr().ToString().getData(),
				           pNetClient->getMsgConn()->getPingTime());
				if (pNetClient->getMsgConn() != pNetClient->getDataConn())
					AddLineFmt(LoadResStr("IDS_NET_CLIENT_INFO_CONNDATA"),
					           ::Network.NetIO.getNetIOName(pNetClient->getDataConn()->getNetClass()),
					           pNetClient->getDataConn()->getPeerAddr().ToString().getData(),
					           pNetClient->getDataConn()->getPingTime());
			}
			else
				AddLine(LoadResStr("IDS_NET_CLIENT_INFO_NOCONNECTIONS"));
		}
	}
	// update done
	EndUpdateText();
}