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"
19 #include "network/C4Network2.h"
21 
22 #include <stdio.h>
23 
24 #include <unordered_map>
25 #include <functional>
26 #include <random>
27 #include <stdexcept>
28 
30 {
31 public:
35  rng = std::bind(std::uniform_int_distribution<CID>(1/*, max*/), std::ref(random_device));
36  }
37 private:
38  std::random_device random_device;
39  std::function<CID()> rng;
40  std::unordered_map<addr_t, CID> peer_ids;
41  std::unordered_map<CID, addr_t> peer_addrs;
42  // Event handlers
43  virtual bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *OwnAddr, C4NetIO *pNetIO) {
44  CID nid;
45  do {
46  nid = rng();
47  } while(peer_addrs.count(nid) && !nid);
48  peer_ids.emplace(AddrPeer, nid);
49  peer_addrs.emplace(nid, AddrPeer);
50  Send(C4NetpuncherPacketAssID(nid).PackTo(AddrPeer));
51  printf("Punched %s... #%u\n", AddrPeer.ToString().getData(), nid);
52  return true;
53  }
54  virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) {
55  auto& addr = rPacket.getAddr();
56  auto unpack = C4NetpuncherPacket::Construct(rPacket);
57  if (!unpack || unpack->GetType() != PID_Puncher_SReq) { Close(addr); return; }
58  auto other_it = peer_addrs.find(dynamic_cast<C4NetpuncherPacketSReq*>(unpack.get())->GetID());
59  if (other_it == peer_addrs.end()) return; // Might be nice to return some kind of error, for purposes of debugging.
60  Send(C4NetpuncherPacketCReq(other_it->second).PackTo(addr));
61  Send(C4NetpuncherPacketCReq(addr).PackTo(other_it->second));
62  }
63  virtual void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason) {
64  auto it = peer_ids.find(AddrPeer);
65  if (it == peer_ids.end()) {
66  printf("ERROR: closing connection for %s: (%s) but no connection is known\n", AddrPeer.ToString().getData(), szReason);
67  return;
68  }
69  peer_addrs.erase(it->second);
70  peer_ids.erase(it);
71  printf("Stopped punching %s: %s...\n", AddrPeer.ToString().getData(), szReason);
72  };
73 } Puncher;
74 
75 int main(int argc, char * argv[])
76 {
77  // Log
78  printf("Starting puncher...\n");
79 
80  // Get port
81  uint16_t iPort = C4NetStdPortPuncher;
82  if (argc == 2)
83  {
84  iPort = strtoul(argv[1], nullptr, 10);
85  if (!iPort) iPort = C4NetStdPortPuncher;
86  }
87 
88  // Initialize
89  if (!Puncher.Init(iPort))
90  {
91  fprintf(stderr, "Could not initialize puncher: %s", Puncher.GetError());
92  return 1;
93  }
94 
95  // Log
96  printf("Listening on port %d...\n", iPort);
97 
98  // Execute forever
99  for (;;)
100  {
101  Puncher.ExecuteUntil(-1);
102  fprintf(stderr, "ERROR: %s\n", Puncher.GetError());
103  }
104 
105  return 0;
106 }
107 
108 // Necessary to satisfy the linker.
109 void RecordRandom(uint32_t range, uint32_t val) {}
C4NetIOPacket PackTo(const C4NetIO::addr_t &) const
C4NetpuncherID::value CID
Definition: main.cpp:32
C4PuncherServer Puncher
virtual const char * GetError() const
Definition: C4NetIO.h:285
static std::unique_ptr< C4NetpuncherPacket > Construct(const C4NetIOPacket &rpack)
virtual bool Send(const C4NetIOPacket &rPacket)
Definition: C4NetIO.cpp:2696
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:316
virtual bool Close()
Definition: C4NetIO.cpp:2601
C4PuncherServer()
Definition: main.cpp:33
bool ExecuteUntil(int iTimeout=-1)
EndpointAddress addr_t
Definition: C4NetIO.h:212
virtual void SetCallback(CBClass *pnCallback)
Definition: C4NetIO.h:919
virtual bool Init(uint16_t iPort=addr_t::IPPORT_NONE)
Definition: C4NetIO.cpp:2434
int main(int argc, char *argv[])
Definition: main.cpp:75
void RecordRandom(uint32_t range, uint32_t val)
Definition: main.cpp:109
const int16_t C4NetStdPortPuncher
Definition: C4Network2.h:33