23 #include <unordered_map>
31 rng = std::bind(std::uniform_int_distribution<CID>(1), std::ref(random_device));
34 std::random_device random_device;
35 std::function<
CID()> rng;
36 std::unordered_map<addr_t, CID> peer_ids;
37 std::unordered_map<CID, addr_t> peer_addrs;
43 }
while(peer_addrs.count(nid) && !nid);
44 peer_ids.emplace(AddrPeer, nid);
45 peer_addrs.emplace(nid, AddrPeer);
46 printf(
"Punched %s... #%u\n", AddrPeer.ToString().getData(), nid);
52 if (!unpack) {
Close(addr);
return; }
53 switch (unpack->GetType()) {
55 auto it = peer_ids.find(addr);
56 if (it != peer_ids.end()) {
57 Send(C4NetpuncherPacketAssID(it->second).PackTo(addr));
58 printf(
"Host: #%u\n", it->second);
63 auto other_it = peer_addrs.find(
dynamic_cast<C4NetpuncherPacketSReq*
>(unpack.get())->GetID());
64 if (other_it == peer_addrs.end())
return;
73 void OnDisconn(
const addr_t &AddrPeer,
C4NetIO *pNetIO,
const char *szReason)
override {
74 auto it = peer_ids.find(AddrPeer);
75 if (it == peer_ids.end()) {
76 printf(
"ERROR: closing connection for %s: (%s) but no connection is known\n", AddrPeer.ToString().getData(), szReason);
79 peer_addrs.erase(it->second);
81 printf(
"Stopped punching %s: %s...\n", AddrPeer.ToString().getData(), szReason);
85 int main(
int argc,
char * argv[])
88 printf(
"Starting puncher...\n");
94 iPort = strtoul(argv[1],
nullptr, 10);
101 fprintf(stderr,
"Could not initialize puncher: %s",
Puncher.
GetError());
106 printf(
"Listening on port %d...\n", iPort);
const int16_t C4NetStdPortPuncher
virtual const char * GetError() const
const C4NetIO::addr_t & getAddr() const
bool Send(const C4NetIOPacket &rPacket) override
void SetCallback(CBClass *pnCallback) override
bool Init(uint16_t iPort=addr_t::IPPORT_NONE) override
C4NetIOPacket PackTo(const C4NetIO::addr_t &) const
static std::unique_ptr< C4NetpuncherPacket > Construct(const C4NetIOPacket &rpack)
C4NetpuncherID::value CID
bool ExecuteUntil(int iTimeout=-1)
int main(int argc, char *argv[])
void RecordRandom(uint32_t range, uint32_t val)