Sockets.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. Copyright (c) 2009-2010 Christopher A. Taylor. All rights reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions are met:
  5. * Redistributions of source code must retain the above copyright notice,
  6. this list of conditions and the following disclaimer.
  7. * Redistributions in binary form must reproduce the above copyright notice,
  8. this list of conditions and the following disclaimer in the documentation
  9. and/or other materials provided with the distribution.
  10. * Neither the name of LibCat nor the names of its contributors may be used
  11. to endorse or promote products derived from this software without
  12. specific prior written permission.
  13. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  14. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  17. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  23. POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef CAT_SOCKETS_HPP
  26. #define CAT_SOCKETS_HPP
  27. #include <cat/Platform.hpp>
  28. #include <string>
  29. #if defined(CAT_OS_WINDOWS)
  30. # include <WS2tcpip.h>
  31. #else
  32. # include <unistd.h>
  33. #endif
  34. #define CAT_IP4_LOOPBACK "127.0.0.1"
  35. #define CAT_IP6_LOOPBACK "::1"
  36. namespace cat {
  37. //// Data Types
  38. #if defined(CAT_OS_WINDOWS)
  39. typedef SOCKET Socket;
  40. CAT_INLINE bool CloseSocket(Socket s) { return !closesocket(s); }
  41. #else
  42. typedef int Socket;
  43. static const Socket INVALID_SOCKET = -1;
  44. static const int SOCKET_ERROR = -1;
  45. CAT_INLINE bool CloseSocket(Socket s) { return !close(s); }
  46. #endif
  47. typedef u16 Port;
  48. #pragma pack(push)
  49. #pragma pack(1)
  50. // Wrapper for IPv4 and IPv6 addresses
  51. class NetAddr
  52. {
  53. union
  54. {
  55. u8 v6_bytes[16];
  56. u16 v6_words[8];
  57. u64 v6[2];
  58. struct {
  59. u32 v4;
  60. u32 v4_padding[3];
  61. };
  62. } _ip; // Network order
  63. union
  64. {
  65. u32 _valid;
  66. struct {
  67. Port _port; // Host order
  68. u16 _family; // Host order
  69. };
  70. };
  71. public:
  72. static const int IP4_BYTES = 4;
  73. static const int IP6_BYTES = 16;
  74. typedef sockaddr_in6 SockAddr;
  75. public:
  76. CAT_INLINE NetAddr() {}
  77. NetAddr(const char *ip_str, Port port = 0);
  78. NetAddr(const sockaddr_in6 &addr);
  79. NetAddr(const sockaddr_in &addr);
  80. NetAddr(const sockaddr *addr);
  81. NetAddr(int a, int b, int c, int d, Port port = 0);
  82. public:
  83. NetAddr(const NetAddr &addr);
  84. NetAddr &operator=(const NetAddr &addr);
  85. public:
  86. bool Wrap(const sockaddr_in6 &addr);
  87. bool Wrap(const sockaddr_in &addr);
  88. bool Wrap(const sockaddr *addr);
  89. public:
  90. // Promote an IPv4 address to an IPv6 address if needed
  91. bool PromoteTo6();
  92. // Demote an IPv6 address to an IPv4 address if possible,
  93. // otherwise marks address as invalid and returns false
  94. bool DemoteTo4();
  95. CAT_INLINE bool Convert(bool To6) { if (To6) return PromoteTo6(); else return DemoteTo4(); }
  96. public:
  97. CAT_INLINE bool Valid() const { return _valid != 0; }
  98. CAT_INLINE bool Is6() const { return _family == AF_INET6; }
  99. CAT_INLINE const u32 GetIP4() const { return _ip.v4; }
  100. CAT_INLINE const u64 *GetIP6() const { return _ip.v6; }
  101. CAT_INLINE Port GetPort() const { return _port; }
  102. CAT_INLINE void SetPort(Port port) { _port = port; }
  103. // Mark the address as invalid
  104. CAT_INLINE void Invalidate() { _valid = 0; }
  105. public:
  106. bool EqualsIPOnly(const NetAddr &addr) const;
  107. bool operator==(const NetAddr &addr) const;
  108. bool operator!=(const NetAddr &addr) const;
  109. public:
  110. // To validate external input; don't want clients connecting
  111. // to their local network instead of the actual game server.
  112. bool IsInternetRoutable();
  113. // Returns true if the address is routable on local network or Internet.
  114. // Returns false if the address is IPv4 multicast, loopback, or weird.
  115. bool IsRoutable();
  116. public:
  117. bool SetFromString(const char *ip_str, Port port = 0);
  118. std::string IPToString() const;
  119. bool SetFromRawIP(const u8 *ip_binary, int bytes);
  120. bool SetFromDotDecimals(int a, int b, int c, int d, Port port = 0);
  121. public:
  122. bool Unwrap(SockAddr &addr, int &addr_len, bool PromoteToIP6 = false) const;
  123. };
  124. #pragma pack(pop)
  125. //// Helper Functions
  126. // Run startup and cleanup functions needed under some OS
  127. bool StartupSockets(); // returns false on error
  128. void CleanupSockets();
  129. // inout_OnlyIPv4: Indicates that only IPv4 is requested by caller
  130. // Sets OnlyIPv4 if IPv6 will be unsupported
  131. // Returns true on success
  132. bool CreateSocket(int type, int protocol, bool SupportIPv4, Socket &out_s, bool &inout_OnlyIPv4);
  133. // Returns true on success
  134. bool NetBind(Socket s, Port port, bool OnlyIPv4);
  135. // Returns 0 on failure
  136. Port GetBoundPort(Socket s);
  137. //// Error Codes
  138. // Returns a string describing the last error from Winsock2 API
  139. std::string SocketGetLastErrorString();
  140. std::string SocketGetErrorString(int code);
  141. } // namespace cat
  142. #endif // CAT_SOCKETS_HPP
粤ICP备19079148号