NAT.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: NAT.h /////////////////////////////////////////////////////////////////////////////////
  24. // Author: Bryan Cleveland April 2002
  25. // Desc: Resolves NAT'd IPs and port numbers for the other players in a game.
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #pragma once
  28. #ifndef __NAT_H
  29. #define __NAT_H
  30. #include "Lib\BaseType.h"
  31. #include "GameNetwork/NetworkInterface.h"
  32. #include "GameNetwork/FirewallHelper.h"
  33. class Transport;
  34. class GameSlot;
  35. enum NATStateType {
  36. NATSTATE_IDLE,
  37. NATSTATE_DOCONNECTIONPATHS,
  38. NATSTATE_WAITFORSTATS,
  39. NATSTATE_DONE,
  40. NATSTATE_FAILED
  41. };
  42. enum NATConnectionState {
  43. NATCONNECTIONSTATE_NOSTATE,
  44. NATCONNECTIONSTATE_WAITINGTOBEGIN,
  45. // NATCONNECTIONSTATE_NETGEARDELAY,
  46. NATCONNECTIONSTATE_WAITINGFORMANGLERRESPONSE,
  47. NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT,
  48. NATCONNECTIONSTATE_WAITINGFORRESPONSE,
  49. NATCONNECTIONSTATE_DONE,
  50. NATCONNECTIONSTATE_FAILED
  51. };
  52. struct ConnectionNodeType {
  53. FirewallHelperClass::tFirewallBehaviorType m_behavior; ///< the NAT/Firewall behavior of this node.
  54. UnsignedInt m_slotIndex; ///< the player list index of this node.
  55. };
  56. class NAT {
  57. public:
  58. NAT();
  59. virtual ~NAT();
  60. NATStateType update();
  61. void attachSlotList(GameSlot **slotList, Int localSlot, UnsignedInt localIP);
  62. void establishConnectionPaths();
  63. Int getSlotPort(Int slot);
  64. Transport * getTransport(); ///< return the newly created Transport layer that has all the connections and whatnot.
  65. // Notification messages from GameSpy
  66. void processGlobalMessage(Int slotNum, const char *options);
  67. protected:
  68. NATConnectionState connectionUpdate(); ///< the update function for the connections.
  69. void sendMangledSourcePort(); ///< starts the process to get the next mangled source port.
  70. void processManglerResponse(UnsignedShort mangledPort);
  71. Bool allConnectionsDoneThisRound();
  72. Bool allConnectionsDone();
  73. void generatePortNumbers(GameSlot **slotList, Int localSlot); ///< generate all of the slots' port numbers to be used.
  74. void doThisConnectionRound(); ///< compute who will connect with who for this round.
  75. void setConnectionState(Int nodeNumber, NATConnectionState state); ///< central point for changing a connection's state.
  76. void sendAProbe(UnsignedInt ip, UnsignedShort port, Int fromNode); ///< send a "PROBE" packet to this IP and port.
  77. void notifyTargetOfProbe(GameSlot *targetSlot);
  78. void notifyUsersOfConnectionDone(Int nodeIndex);
  79. void notifyUsersOfConnectionFailed(Int nodeIndex);
  80. void sendMangledPortNumberToTarget(UnsignedShort mangledPort, GameSlot *targetSlot);
  81. void probed(Int nodeNumber);
  82. void gotMangledPort(Int nodeNumber, UnsignedShort mangledPort);
  83. void gotInternalAddress(Int nodeNumber, UnsignedInt address);
  84. void connectionComplete(Int slotIndex);
  85. void connectionFailed(Int slotIndex);
  86. Transport *m_transport;
  87. GameSlot **m_slotList;
  88. NATStateType m_NATState;
  89. Int m_localNodeNumber; ///< The node number of the local player.
  90. Int m_targetNodeNumber; ///< The node number of the player we are connecting to this round.
  91. UnsignedInt m_localIP; ///< The IP of the local computer.
  92. UnsignedInt m_numNodes; ///< The number of players we have to connect together.
  93. UnsignedInt m_connectionRound; ///< The "round" of connections we are currently on.
  94. Int m_numRetries;
  95. Int m_maxNumRetriesAllowed;
  96. UnsignedShort m_packetID;
  97. UnsignedShort m_spareSocketPort;
  98. time_t m_manglerRetryTime;
  99. Int m_manglerRetries;
  100. UnsignedShort m_previousSourcePort;
  101. Bool m_beenProbed; ///< have I been notified that I've been probed this round?
  102. UnsignedInt m_manglerAddress;
  103. time_t m_timeTillNextSend; ///< The number of milliseconds till we send to the other guy's port again.
  104. NATConnectionState m_connectionStates[MAX_SLOTS]; ///< connection states for this round for all the nodes.
  105. ConnectionNodeType m_connectionNodes[MAX_SLOTS]; ///< info regarding the nodes that are being connected.
  106. UnsignedShort m_sourcePorts[MAX_SLOTS]; ///< the source ports that the other players communicate to us on.
  107. Bool m_myConnections[MAX_SLOTS]; ///< keeps track of all the nodes I've connected to. For keepalive.
  108. time_t m_nextKeepaliveTime; ///< the next time we will send out our keepalive packets.
  109. static Int m_connectionPairs[MAX_SLOTS-1][MAX_SLOTS-1][MAX_SLOTS];
  110. Int m_connectionPairIndex;
  111. UnsignedShort m_startingPortNumber; ///< the starting port number for this game. The slots all get port numbers with their port numbers based on this number.
  112. ///< this is done so that games that are played right after each other with the same players in the same
  113. ///< slot order will not use the old source port allocation scheme in case their NAT
  114. ///< hasn't timed out that connection.
  115. time_t m_nextPortSendTime; ///< Last time we sent our mangled port number to our target this round.
  116. time_t m_timeoutTime; ///< the time at which we will time out waiting for the other player's port number.
  117. time_t m_roundTimeout; ///< the time at which we will time out this connection round.
  118. static Int m_timeBetweenRetries; // 1 second between retries sounds good to me.
  119. static time_t m_manglerRetryTimeInterval; // sounds good to me.
  120. static Int m_maxAllowedManglerRetries; // works for me.
  121. static time_t m_keepaliveInterval; // 15 seconds between keepalive packets seems good.
  122. static time_t m_timeToWaitForPort; // wait for ten seconds for the other player's port number.
  123. static time_t m_timeForRoundTimeout; // wait for at most ten seconds for each connection round to finish.
  124. };
  125. extern NAT *TheNAT;
  126. #endif // #ifndef __NAT_H