1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2013-2018, The OpenClonk Team and contributors
6 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18/* network i/o, featuring tcp, udp and multicast */
19
20#pragma once
21
22#include "C4Network2Address.h"
23#include "Standard.h"
24#include "StdSync.h"
25#include "StdBuf.h"
26#include "StdCompiler.h"
27#include "StdScheduler.h"
28
29#include <memory>
30#include <vector>
31
32
33#include <cstring>
34#include <vector>
35
36class C4Network2Address;
37
38// net i/o base class
39class C4NetIO : public StdSchedulerProc
40{
41public:
42 C4NetIO();
43 virtual ~C4NetIO();
44
45 using addr_t = C4Network2EndpointAddress;
46
47 static std::vector<C4Network2HostAddress> GetLocalAddresses(bool unsorted = false);
48 static void SortAddresses(std::vector<C4Network2Address> &addresses);
49
50 // callback class
51 class CBClass
52 {
53 public:
54 virtual bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *pOwnAddr, C4NetIO *pNetIO) { return true; }
55 virtual void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason) {}
56 virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) = 0;
57 virtual ~CBClass() {}
58 };
59
60 // used to explicitly callback to a specific class
61 template <class T>
62 class CBProxy : public CBClass
63 {
64 T *pTarget;
65
66 public:
67 CBProxy *operator()(T *pnTarget) { pTarget = pnTarget; return this; }
68
69 virtual bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *pOwnAddr, C4NetIO *pNetIO) override
70 {
71 return pTarget->T::OnConn(AddrPeer, AddrConnect, pOwnAddr, pNetIO);
72 }
73
74 virtual void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason) override
75 {
76 pTarget->T::OnDisconn(AddrPeer, pNetIO, szReason);
77 }
78
79 virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) override
80 {
81 pTarget->T::OnPacket(rPacket, pNetIO);
82 }
83 };
84
85#define NETIO_CREATE_CALLBACK_PROXY(ForClass, ProxyName) \
86 friend class C4NetIO::CBProxy<ForClass>; \
87 C4NetIO::CBProxy<ForClass> ProxyName
88
89 // *** interface
90
91 // * not multithreading safe
92 virtual bool Init(uint16_t iPort = addr_t::IPPORT_NONE) = 0;
93 virtual bool Close() = 0;
94
95 virtual bool Execute(int iTimeout = -1) override = 0; // (for StdSchedulerProc)
96
97 // * multithreading safe
98 virtual bool Connect(const addr_t &addr) = 0; // async!
99 virtual bool Close(const addr_t &addr) = 0;
100
101 virtual bool Send(const class C4NetIOPacket &rPacket) = 0;
102 virtual bool SetBroadcast(const addr_t &addr, bool fSet = true) = 0;
103 virtual bool Broadcast(const class C4NetIOPacket &rPacket) = 0;
104
105 // statistics
106 virtual bool GetStatistic(int *pBroadcastRate) = 0;
107 virtual bool GetConnStatistic(const addr_t &addr, int *pIRate, int *pORate, int *pLoss) = 0;
108 virtual void ClearStatistic() = 0;
109
110protected:
111 // Makes IPv4 connections from an IPv6 socket work.
112 bool InitIPv6Socket(SOCKET socket);
113
114 // *** errors
115protected:
116 StdStrBuf Error;
117 void SetError(const char *strnError, bool fSockErr = false);
118
119public:
120 virtual const char *GetError() const { return Error.getData(); }
121 void ResetError() { Error.Clear(); }
122
123 // *** callbacks
124 virtual void SetCallback(CBClass *pnCallback) = 0;
125};
126
127// packet class
128class C4NetIOPacket : public StdBuf
129{
130public:
131 C4NetIOPacket();
132
133 // construct from memory (copies / references data)
134 C4NetIOPacket(const void *pnData, size_t inSize, bool fCopy = false, const C4NetIO::addr_t &naddr = C4NetIO::addr_t());
135 // construct from buffer (takes data, if possible)
136 explicit C4NetIOPacket(const StdBuf &Buf, const C4NetIO::addr_t &naddr = C4NetIO::addr_t());
137
138 ~C4NetIOPacket();
139
140protected:
141 // address
142 C4NetIO::addr_t addr;
143
144public:
145 const C4NetIO::addr_t &getAddr() const { return addr; }
146
147 uint8_t getStatus() const { return getSize() ? *getPtr<char>() : 0; }
148 StdBuf getPBuf() const { return getSize() ? getPart(iStart: 1, inSize: getSize() - 1) : getRef(); }
149 const char *getPData() const { return getSize() ? getPtr<char>(pos: 1) : nullptr; }
150 std::size_t getPSize() const { return getSize() ? getSize() - 1 : 0; }
151
152 // Some overloads
153 C4NetIOPacket getRef() const { return C4NetIOPacket(StdBuf::getRef(), addr); }
154 C4NetIOPacket Duplicate() const { return C4NetIOPacket(StdBuf::Duplicate(), addr); }
155 // change addr
156 void SetAddr(const C4NetIO::addr_t &naddr) { addr = naddr; }
157
158 // delete contents
159 void Clear();
160};
161
162// tcp network i/o
163class C4NetIOTCP : public C4NetIO, protected CStdCSecExCallback
164{
165public:
166 C4NetIOTCP();
167 virtual ~C4NetIOTCP();
168
169 // Socket is an unconnected, but bound socket.
170 class Socket
171 {
172 SOCKET sock;
173 Socket(const SOCKET s) : sock{s} {}
174 friend class C4NetIOTCP;
175
176 public:
177 ~Socket();
178 // GetAddress returns the address the socket is bound to.
179 C4NetIO::addr_t GetAddress() const;
180 };
181
182 // *** interface
183
184 // * not multithreading safe
185 virtual bool Init(uint16_t iPort = addr_t::IPPORT_NONE) override;
186 virtual bool InitBroadcast(addr_t *pBroadcastAddr);
187 virtual bool Close() override;
188 virtual bool CloseBroadcast();
189
190 virtual bool Execute(int iMaxTime = StdSync::Infinite) override;
191
192 // * multithreading safe
193 std::unique_ptr<Socket> Bind(const addr_t &addr);
194 bool Connect(const addr_t &addr, std::unique_ptr<Socket> socket);
195 virtual bool Connect(const addr_t &addr) override;
196 virtual bool Close(const addr_t &addr) override;
197
198 virtual bool Send(const C4NetIOPacket &rPacket) override;
199 virtual bool Broadcast(const C4NetIOPacket &rPacket) override;
200 virtual bool SetBroadcast(const addr_t &addr, bool fSet = true) override;
201
202 virtual void UnBlock();
203#ifdef _WIN32
204 virtual HANDLE GetEvent() override;
205#else
206 virtual void GetFDs(std::vector<pollfd> &fds) override;
207#endif
208
209 // statistics
210 virtual bool GetStatistic(int *pBroadcastRate) override;
211 virtual bool GetConnStatistic(const addr_t &addr, int *pIRate, int *pORate, int *pLoss) override;
212 virtual void ClearStatistic() override;
213
214protected:
215 // * overridables (packet format)
216
217 // Append packet data to output buffer
218 virtual void PackPacket(const C4NetIOPacket &rPacket, StdBuf &rOutBuf);
219
220 // Extract a packet from the start of the input buffer (if possible) and call OnPacket.
221 // Should return the numer of bytes used.
222 virtual size_t UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &Addr);
223
224 // *** data
225
226 // peer class
227 class Peer
228 {
229 public:
230 Peer(const C4NetIO::addr_t &naddr, SOCKET nsock, C4NetIOTCP *pnParent);
231 ~Peer();
232
233 protected:
234 // constants
235 static const unsigned int iTCPHeaderSize; // = 28 + 24; // (bytes)
236 static const unsigned int iMinIBufSize; // = 8192; // (bytes)
237 // parent
238 C4NetIOTCP *const pParent;
239 // addr
240 C4NetIO::addr_t addr;
241 // socket connected
242 SOCKET sock;
243 // incoming & outgoing buffer
244 StdBuf IBuf, OBuf;
245 int iIBufUsage;
246 // statistics
247 int iIRate, iORate;
248 // status (1 = open, 0 = closed)
249 bool fOpen;
250 // selected for broadcast?
251 bool fDoBroadcast;
252 // IO critical sections
253 CStdCSec ICSec; CStdCSec OCSec;
254
255 public:
256 // data access
257 const C4NetIO::addr_t &GetAddr() const { return addr; }
258 SOCKET GetSocket() const { return sock; }
259 int GetIRate() const { return iIRate; }
260 int GetORate() const { return iORate; }
261 // send a packet to this peer
262 bool Send(const C4NetIOPacket &rPacket);
263 // send as much data of the interal outgoing buffer as possible
264 bool Send();
265 // request buffer space for new input. Must call OnRecv or NoRecv afterwards!
266 void *GetRecvBuf(int iSize);
267 // called after the buffer returned by GetRecvBuf has been filled with fresh data
268 void OnRecv(int iSize);
269 // close socket
270 void Close();
271 // test: open?
272 bool Open() const { return fOpen; }
273 // selected for broadcast?
274 bool doBroadcast() const { return fDoBroadcast; }
275 // outgoing data waiting?
276 bool hasWaitingData() const { return !OBuf.isNull(); }
277 // select/unselect peer
278 void SetBroadcast(bool fSet) { fDoBroadcast = fSet; }
279 // statistics
280 void ClearStatistics();
281
282 public:
283 // next peer
284 Peer *Next;
285 };
286
287 friend class Peer;
288
289 // peer list
290 Peer *pPeerList;
291
292 // small list for waited-for connections
293 struct ConnectWait
294 {
295 SOCKET sock;
296 addr_t addr;
297
298 ConnectWait *Next;
299 }
300 *pConnectWaits;
301
302 CStdCSecEx PeerListCSec;
303 CStdCSec PeerListAddCSec;
304
305 // initialized?
306 bool fInit;
307
308 // listen socket
309 uint16_t iListenPort;
310 SOCKET lsock{INVALID_SOCKET};
311
312#ifdef _WIN32
313 // event indicating network activity
314 HANDLE Event;
315#else
316 // Pipe used for cancelling select
317 int Pipe[2];
318#endif
319
320 // *** implementation
321
322 bool Listen(uint16_t inListenPort);
323
324 SOCKET CreateSocket(addr_t::AddressFamily family);
325 bool Connect(const addr_t &addr, SOCKET nsock);
326
327 Peer *Accept(SOCKET nsock = INVALID_SOCKET, const addr_t &ConnectAddr = addr_t());
328 Peer *GetPeer(const addr_t &addr);
329 void OnShareFree(CStdCSecEx *pCSec) override;
330
331 void AddConnectWait(SOCKET sock, const addr_t &addr);
332 ConnectWait *GetConnectWait(const addr_t &addr);
333 void ClearConnectWaits();
334
335 // *** callbacks
336
337public:
338 virtual void SetCallback(CBClass *pnCallback) override { pCB = pnCallback; }
339
340private:
341 CBClass *pCB;
342};
343
344// simple udp network i/o
345// - No connections
346// - Delivery not garantueed
347// - Broadcast will multicast the packet to all clients with the same broadcast address.
348class C4NetIOSimpleUDP : public C4NetIO
349{
350public:
351 C4NetIOSimpleUDP();
352 virtual ~C4NetIOSimpleUDP();
353
354 virtual bool Init(uint16_t iPort = addr_t::IPPORT_NONE) override;
355 virtual bool InitBroadcast(addr_t *pBroadcastAddr);
356 virtual bool Close() override;
357 virtual bool CloseBroadcast();
358
359 virtual bool Execute(int iMaxTime = StdSync::Infinite) override;
360
361 virtual bool Send(const C4NetIOPacket &rPacket) override;
362 virtual bool Broadcast(const C4NetIOPacket &rPacket) override;
363
364 virtual void UnBlock();
365#ifdef _WIN32
366 virtual HANDLE GetEvent() override;
367#else
368 virtual void GetFDs(std::vector<pollfd> &fds) override;
369#endif
370
371 // not implemented
372 virtual bool Connect(const addr_t &addr) override { assert(false); return false; }
373 virtual bool Close(const addr_t &addr) override { assert(false); return false; }
374
375 virtual bool SetBroadcast(const addr_t &addr, bool fSet = true) override { assert(false); return false; }
376
377 virtual bool GetStatistic(int *pBroadcastRate) override { assert(false); return false; }
378
379 virtual bool GetConnStatistic(const addr_t &addr, int *pIRate, int *pORate, int *pLoss) override
380 {
381 assert(false); return false;
382 }
383
384 virtual void ClearStatistic() override { assert(false); }
385
386private:
387 // status
388 bool fInit;
389 bool fMultiCast;
390 uint16_t iPort;
391
392 // the socket and the associated event
393 SOCKET sock{INVALID_SOCKET};
394#ifdef _WIN32
395 HANDLE hEvent;
396#else
397 int Pipe[2];
398#endif
399
400 // multicast
401 addr_t MCAddr; ipv6_mreq MCGrpInfo;
402 bool fMCLoopback;
403
404 // multibind
405 int fAllowReUse;
406
407protected:
408 // multicast address
409 const addr_t &getMCAddr() const { return MCAddr; }
410
411 // (try to) control loopback
412 bool SetMCLoopback(int fLoopback);
413 bool getMCLoopback() const { return fMCLoopback; }
414
415 // enable multi-bind (call before Init!)
416 void SetReUseAddress(bool fAllow);
417
418private:
419 // socket wait (check for readability)
420 enum WaitResult { WR_Timeout, WR_Readable, WR_Cancelled, WR_Error = -1, };
421 WaitResult WaitForSocket(int iTimeout);
422
423 // *** callbacks
424public:
425 virtual void SetCallback(CBClass *pnCallback) override { pCB = pnCallback; }
426
427private:
428 CBClass *pCB;
429};
430
431// udp network i/o
432// - Connection are emulated
433// - Delivery garantueed
434// - Broadcast will automatically be activated on one side if it's active on the other side.
435// If the peer can't be reached through broadcasting, packets will be sent directly.
436class C4NetIOUDP : public C4NetIOSimpleUDP, protected CStdCSecExCallback
437{
438public:
439 C4NetIOUDP();
440 virtual ~C4NetIOUDP();
441
442 // *** interface
443
444 virtual bool Init(uint16_t iPort = addr_t::IPPORT_NONE) override;
445 virtual bool InitBroadcast(addr_t *pBroadcastAddr) override;
446 virtual bool Close() override;
447 virtual bool CloseBroadcast() override;
448
449 virtual bool Execute(int iMaxTime = StdSync::Infinite) override;
450
451 virtual bool Connect(const addr_t &addr) override;
452 virtual bool Close(const addr_t &addr) override;
453
454 virtual bool Send(const C4NetIOPacket &rPacket) override;
455 bool SendDirect(C4NetIOPacket &&packet); // (mt-safe)
456 virtual bool Broadcast(const C4NetIOPacket &rPacket) override;
457 virtual bool SetBroadcast(const addr_t &addr, bool fSet = true) override;
458
459 virtual int GetTimeout() override;
460
461 virtual bool GetStatistic(int *pBroadcastRate) override;
462 virtual bool GetConnStatistic(const addr_t &addr, int *pIRate, int *pORate, int *pLoss) override;
463 virtual void ClearStatistic() override;
464
465protected:
466 // *** data
467
468 // internal packet type ids
469 enum IPTypeID : uint8_t
470 {
471 IPID_Ping = 0,
472 IPID_Test = 1,
473 IPID_Conn = 2,
474 IPID_ConnOK = 3,
475 IPID_AddAddr = 7,
476 IPID_Data = 4,
477 IPID_Check = 5,
478 IPID_Close = 6,
479 };
480
481 // packet structures
482 struct BinAddr;
483 struct PacketHdr; struct TestPacket; struct ConnPacket; struct ConnOKPacket; struct AddAddrPacket;
484 struct DataPacketHdr; struct CheckPacketHdr; struct ClosePacket;
485
486 // constants
487 static const unsigned int iVersion; // = 2;
488
489 static const unsigned int iStdTimeout, // = 1000, // (ms)
490 iCheckInterval; // = 1000 // (ms)
491
492 static const unsigned int iMaxOPacketBacklog; // = 100;
493
494 static const unsigned int iUDPHeaderSize; // = 8 + 24; // (bytes)
495
496 // packet class
497 class PacketList;
498 class Packet
499 {
500 friend class PacketList;
501
502 public:
503 // constants / structures
504 static const size_t MaxSize; // = 1024;
505 static const size_t MaxDataSize; // = MaxSize - sizeof(Header);
506
507 // types used for packing
508 typedef uint32_t nr_t;
509
510 // construction / destruction
511 Packet();
512 Packet(C4NetIOPacket &&rnData, nr_t inNr);
513 ~Packet();
514
515 protected:
516 // data
517 nr_t iNr;
518 C4NetIOPacket Data;
519 bool *pFragmentGot;
520
521 public:
522 // data access
523 C4NetIOPacket &GetData() { return Data; }
524 const C4NetIOPacket &GetData() const { return Data; }
525 nr_t GetNr() const { return iNr; }
526 bool Empty() const { return Data.isNull(); }
527
528 // fragmention
529 nr_t FragmentCnt() const;
530 C4NetIOPacket GetFragment(nr_t iFNr, bool fBroadcastFlag = false) const;
531 bool Complete() const;
532 bool FragmentPresent(nr_t iFNr) const;
533 bool AddFragment(const C4NetIOPacket &Packet, const C4NetIO::addr_t &addr);
534
535 protected:
536 ::size_t FragmentSize(nr_t iFNr) const;
537 // list
538 Packet *Next, *Prev;
539 };
540
541 friend class Packet;
542
543 class PacketList
544 {
545 public:
546 PacketList(unsigned int iMaxPacketCnt = ~0);
547 ~PacketList();
548
549 protected:
550 // packet list
551 Packet *pFront, *pBack;
552 // packet counts
553 unsigned int iPacketCnt, iMaxPacketCnt;
554 // critical section
555 CStdCSecEx ListCSec;
556
557 public:
558 Packet *GetPacket(unsigned int iNr);
559 Packet *GetPacketFrgm(unsigned int iNr);
560 Packet *GetFirstPacketComplete();
561 bool FragmentPresent(unsigned int iNr);
562
563 bool AddPacket(Packet *pPacket);
564 bool DeletePacket(Packet *pPacket);
565 void ClearPackets(unsigned int iUntil);
566 void Clear();
567 };
568
569 friend class PacketList;
570
571 // peer class
572 class Peer
573 {
574 public:
575 // construction / destruction
576 Peer(const C4NetIO::addr_t &naddr, C4NetIOUDP *pnParent);
577 ~Peer();
578
579 protected:
580 // constants
581 static const unsigned int iConnectRetries; // = 5
582 static const unsigned int iReCheckInterval; // = 1000 (ms)
583
584 // parent class
585 C4NetIOUDP *const pParent;
586
587 // peer address
588 C4NetIO::addr_t addr;
589 // alternate peer address
590 C4NetIO::addr_t addr2;
591 // the address used by the peer
592 addr_t PeerAddr;
593 // connection status
594 enum ConnStatus
595 {
596 CS_None, CS_Conn, CS_Works, CS_Closed
597 }
598 eStatus;
599 // does multicast work?
600 bool fMultiCast;
601 // selected for broadcast?
602 bool fDoBroadcast;
603 // do callback on connection timeout?
604 bool fConnFailCallback;
605
606 // packet lists (outgoing, incoming, incoming multicast)
607 PacketList OPackets;
608 PacketList IPackets, IMCPackets;
609
610 // packet counters
611 unsigned int iOPacketCounter;
612 unsigned int iIPacketCounter, iRIPacketCounter;
613 unsigned int iIMCPacketCounter, iRIMCPacketCounter;
614
615 unsigned int iMCAckPacketCounter;
616
617 // output critical section
618 CStdCSec OutCSec;
619
620 // connection check time limit
621 unsigned int iNextReCheck;
622 unsigned int iLastPacketAsked, iLastMCPacketAsked;
623
624 // timeout
625 unsigned int iTimeout;
626 unsigned int iRetries;
627
628 // statistics
629 int iIRate, iORate, iLoss;
630 CStdCSec StatCSec;
631
632 public:
633 // data access
634 const C4NetIO::addr_t &GetAddr() const { return addr; }
635 const C4NetIO::addr_t &GetAltAddr() const { return addr2; }
636
637 // initiate connection
638 bool Connect(bool fFailCallback);
639
640 // send something to this computer
641 bool Send(const C4NetIOPacket &rPacket);
642 // check for lost packets
643 bool Check(bool fForceCheck = true);
644
645 // called if something from this peer was received
646 void OnRecv(const C4NetIOPacket &Packet);
647
648 // close connection
649 void Close(const char *szReason);
650 // open?
651 bool Open() const { return eStatus == CS_Works; }
652 // closed?
653 bool Closed() const { return eStatus == CS_Closed; }
654 // multicast support?
655 bool MultiCast() const { return fMultiCast; }
656
657 // acknowledgment check
658 unsigned int GetMCAckPacketCounter() const { return iMCAckPacketCounter; }
659
660 // timeout checking
661 int GetTimeout() { return iTimeout; }
662 void CheckTimeout();
663
664 // selected for broadcast?
665 bool doBroadcast() const { return fDoBroadcast; }
666 // select/unselect peer
667 void SetBroadcast(bool fSet) { fDoBroadcast = fSet; }
668
669 // alternate address
670 void SetAltAddr(const C4NetIO::addr_t &naddr2) { addr2 = naddr2; }
671
672 // statistics
673 int GetIRate() const { return iIRate; }
674 int GetORate() const { return iORate; }
675 void ClearStatistics();
676
677 protected:
678 // * helpers
679 bool DoConn(bool fMC);
680 bool DoCheck(int iAskCnt = 0, int iMCAskCnt = 0, unsigned int *pAskList = nullptr);
681
682 // sending
683 bool SendDirect(const Packet &rPacket, unsigned int iNr = ~0);
684 bool SendDirect(C4NetIOPacket &&rPacket);
685
686 // events
687 void OnConn();
688 void OnClose(const char *szReason);
689
690 // incoming packet list
691 void CheckCompleteIPackets();
692
693 // timeout
694 void SetTimeout(int iLength = iStdTimeout, int iRetryCnt = 0);
695 void OnTimeout();
696
697 public:
698 // next peer
699 Peer *Next;
700 };
701
702 friend class Peer;
703
704 // critical sections
705 CStdCSecEx PeerListCSec;
706 CStdCSec PeerListAddCSec;
707 CStdCSec OutCSec;
708
709 // status
710 bool fInit;
711 bool fMultiCast;
712 uint16_t iPort;
713
714 // peer list
715 Peer *pPeerList;
716
717 // currently initializing - do not process packets, save them back instead
718 bool fSavePacket;
719 C4NetIOPacket LastPacket;
720
721 // multicast support data
722 addr_t MCLoopbackAddr;
723 bool fDelayedLoopbackTest;
724
725 // check timing
726 unsigned int iNextCheck;
727
728 // outgoing packet list (for multicast)
729 PacketList OPackets;
730 unsigned int iOPacketCounter;
731
732 // statistics
733 int iBroadcastRate;
734 CStdCSec StatCSec;
735
736 // callback proxy
737 NETIO_CREATE_CALLBACK_PROXY(C4NetIOUDP, CBProxy);
738
739 // helpers
740
741 // sending
742 bool BroadcastDirect(const Packet &rPacket, unsigned int iNr = ~0u); // (mt-safe)
743
744 // multicast related
745 bool DoLoopbackTest();
746 void ClearMCPackets();
747
748 // peer list
749 void AddPeer(Peer *pPeer);
750 Peer *GetPeer(const addr_t &addr);
751 Peer *ConnectPeer(const addr_t &PeerAddr, bool fFailCallback);
752 void OnShareFree(CStdCSecEx *pCSec) override;
753
754 // connection check
755 void DoCheck();
756
757 // critical section: only one execute at a time
758 CStdCSec ExecuteCSec;
759
760 // debug
761#ifdef C4NETIO_DEBUG
762 int hDebugLog;
763 void OpenDebugLog();
764 void CloseDebugLog();
765 void DebugLogPkt(bool fOut, const C4NetIOPacket &Pkt);
766#endif
767
768 // *** callbacks
769public:
770 virtual void SetCallback(CBClass *pnCallback) override { pCB = pnCallback; }
771
772private:
773 CBClass *pCB;
774
775 // callback interface for C4NetIO
776 virtual bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *pOwnAddr, C4NetIO *pNetIO);
777 virtual void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason);
778 virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO);
779
780 void OnAddAddress(const addr_t &FromAddr, const AddAddrPacket &Packet);
781};
782
783#ifdef _WIN32
784bool AcquireWinSock();
785void ReleaseWinSock();
786#endif
787