OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4PuncherPacket.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 #include "C4Include.h"
18 
20 
21 static const char C4NetpuncherProtocolVersion = 1;
22 // Netpuncher packet header: (1 byte type "Status"), 1 byte version
23 static const size_t HeaderSize = 2, HeaderPSize = 1;
24 
26  pComp->Value(mkNamingAdapt(v4, "IPv4", 0u));
27  pComp->Value(mkNamingAdapt(v6, "IPv6", 0u));
28 }
29 
30 std::unique_ptr<C4NetpuncherPacket> C4NetpuncherPacket::Construct(const C4NetIOPacket& rpack) {
31  if (!rpack.getPData() || *rpack.getPData() != C4NetpuncherProtocolVersion) return nullptr;
32  try {
33  switch (rpack.getStatus())
34  {
35  case PID_Puncher_AssID: return uptr(new C4NetpuncherPacketAssID(rpack));
36  case PID_Puncher_SReq: return uptr(new C4NetpuncherPacketSReq(rpack));
37  case PID_Puncher_CReq: return uptr(new C4NetpuncherPacketCReq(rpack));
38  case PID_Puncher_IDReq: return uptr(new C4NetpuncherPacketIDReq(rpack));
39  default: return nullptr;
40  }
41  }
42  catch (StdCompiler::Exception *e) { delete e; return nullptr; }
43  catch (...) { return nullptr; }
44 }
46  C4NetIOPacket pkt;
47  pkt.SetAddr(addr);
48  StdBuf content(PackInto());
49  char type = GetType();
50  pkt.New(sizeof(type) + sizeof(C4NetpuncherProtocolVersion) + content.getSize());
51  size_t offset = 0;
52  pkt.Write(&type, sizeof(type), offset);
53  offset += sizeof(type);
54  pkt.Write(&C4NetpuncherProtocolVersion, sizeof(C4NetpuncherProtocolVersion), offset);
55  offset += sizeof(C4NetpuncherProtocolVersion);
56  pkt.Write(content, offset);
57  return pkt;
58 }
59 
61  if (rpack.getPSize() < HeaderPSize + 2 + 16) throw "invalid size";
62  uint16_t port = *getBufPtr<uint16_t>(rpack, HeaderSize);
63  addr.SetAddress(C4NetIO::addr_t::Any, port);
64  memcpy(&static_cast<sockaddr_in6*>(&addr)->sin6_addr, getBufPtr<char>(rpack, HeaderSize + sizeof(port)), 16);
65 }
66 
67 StdBuf C4NetpuncherPacketCReq::PackInto() const {
68  StdBuf buf;
69  auto sin6 = static_cast<sockaddr_in6>(addr.AsIPv6());
70  auto port = addr.GetPort();
71  buf.New(sizeof(port) + sizeof(sin6.sin6_addr));
72  size_t offset = 0;
73  buf.Write(&port, sizeof(port), offset);
74  offset += sizeof(port);
75  buf.Write(&sin6.sin6_addr, sizeof(sin6.sin6_addr), offset);
76  static_assert(sizeof(sin6.sin6_addr) == 16, "expected sin6_addr to be 16 bytes");
77  return buf;
78 }
79 
80 template<C4NetpuncherPacketType TYPE>
82  if (rpack.getPSize() < HeaderPSize + sizeof(id)) throw "invalid size";
83  id = *getBufPtr<CID>(rpack, HeaderSize);
84 }
85 
86 template<C4NetpuncherPacketType TYPE>
88  StdBuf buf;
89  auto id = GetID();
90  buf.New(sizeof(id));
91  buf.Write(&id, sizeof(id));
92  return buf;
93 }
C4NetIOPacket PackTo(const C4NetIO::addr_t &) const
Definition: StdBuf.h:29
static std::unique_ptr< C4NetpuncherPacket > Construct(const C4NetIOPacket &rpack)
void SetAddress(const sockaddr *addr)
Definition: C4NetIO.cpp:364
size_t getSize() const
Definition: StdBuf.h:101
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
void CompileFunc(StdCompiler *pComp)
void Value(const T &rStruct)
Definition: StdCompiler.h:161
void New(size_t inSize)
Definition: StdBuf.h:146
virtual C4NetpuncherPacketType GetType() const =0
void Write(const void *pnData, size_t inSize, size_t iAt=0)
Definition: StdBuf.h:153
C4NetpuncherPacketID(const C4NetIOPacket &rpack)
std::unique_ptr< C4NetpuncherPacket > uptr
C4NetpuncherPacketCReq(const C4NetIOPacket &rpack)
uint8_t getStatus() const
Definition: C4NetIO.h:317
size_t getPSize() const
Definition: C4NetIO.h:319
EndpointAddress AsIPv6() const
Definition: C4NetIO.cpp:336
const char * getPData() const
Definition: C4NetIO.h:318
uint16_t GetPort() const
Definition: C4NetIO.cpp:542
void SetAddr(const C4NetIO::addr_t &naddr)
Definition: C4NetIO.h:326
virtual StdBuf PackInto() const =0