OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
main.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2010-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 
17 #include "C4Include.h"
20 #include "network/C4Network2.h"
21 
22 #include <random>
23 #include <unordered_map>
24 
26 {
27 public:
31  rng = std::bind(std::uniform_int_distribution<CID>(1/*, max*/), std::ref(random_device));
32  }
33 private:
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;
38  // Event handlers
39  bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *OwnAddr, C4NetIO *pNetIO) override {
40  CID nid;
41  do {
42  nid = rng();
43  } while(peer_addrs.count(nid) && !nid);
44  peer_ids.emplace(AddrPeer, nid);
45  peer_addrs.emplace(nid, AddrPeer);
46  Send(C4NetpuncherPacketAssID(nid).PackTo(AddrPeer));
47  printf("Punched %s... #%u\n", AddrPeer.ToString().getData(), nid);
48  return true;
49  }
50  void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) override {
51  auto& addr = rPacket.getAddr();
52  auto unpack = C4NetpuncherPacket::Construct(rPacket);
53  if (!unpack || unpack->GetType() != PID_Puncher_SReq) { Close(addr); return; }
54  auto other_it = peer_addrs.find(dynamic_cast<C4NetpuncherPacketSReq*>(unpack.get())->GetID());
55  if (other_it == peer_addrs.end()) return; // Might be nice to return some kind of error, for purposes of debugging.
56  Send(C4NetpuncherPacketCReq(other_it->second).PackTo(addr));
57  Send(C4NetpuncherPacketCReq(addr).PackTo(other_it->second));
58  }
59  void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason) override {
60  auto it = peer_ids.find(AddrPeer);
61  if (it == peer_ids.end()) {
62  printf("ERROR: closing connection for %s: (%s) but no connection is known\n", AddrPeer.ToString().getData(), szReason);
63  return;
64  }
65  peer_addrs.erase(it->second);
66  peer_ids.erase(it);
67  printf("Stopped punching %s: %s...\n", AddrPeer.ToString().getData(), szReason);
68  };
69 } Puncher;
70 
71 int main(int argc, char * argv[])
72 {
73  // Log
74  printf("Starting puncher...\n");
75 
76  // Get port
77  uint16_t iPort = C4NetStdPortPuncher;
78  if (argc == 2)
79  {
80  iPort = strtoul(argv[1], nullptr, 10);
81  if (!iPort) iPort = C4NetStdPortPuncher;
82  }
83 
84  // Initialize
85  if (!Puncher.Init(iPort))
86  {
87  fprintf(stderr, "Could not initialize puncher: %s", Puncher.GetError());
88  return 1;
89  }
90 
91  // Log
92  printf("Listening on port %d...\n", iPort);
93 
94  // Execute forever
95  for (;;)
96  {
98  fprintf(stderr, "ERROR: %s\n", Puncher.GetError());
99  }
100 
101  return 0;
102 }
103 
104 // Necessary to satisfy the linker.
105 void RecordRandom(uint32_t range, uint32_t val) {}
C4NetIOPacket PackTo(const C4NetIO::addr_t &) const
C4NetpuncherID::value CID
Definition: main.cpp:28
bool Close() override
Definition: C4NetIO.cpp:2572
C4PuncherServer Puncher
virtual const char * GetError() const
Definition: C4NetIO.h:284
static std::unique_ptr< C4NetpuncherPacket > Construct(const C4NetIOPacket &rpack)
void SetCallback(CBClass *pnCallback) override
Definition: C4NetIO.h:918
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:315
C4PuncherServer()
Definition: main.cpp:29
bool Send(const C4NetIOPacket &rPacket) override
Definition: C4NetIO.cpp:2667
bool ExecuteUntil(int iTimeout=-1)
EndpointAddress addr_t
Definition: C4NetIO.h:211
int main(int argc, char *argv[])
Definition: main.cpp:71
void RecordRandom(uint32_t range, uint32_t val)
Definition: main.cpp:105
const int16_t C4NetStdPortPuncher
Definition: C4Network2.h:33
bool Init(uint16_t iPort=addr_t::IPPORT_NONE) override
Definition: C4NetIO.cpp:2405