Shadowrun: Awakened 29 September 2011 - Build 871
Sockets.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2009-2010 Christopher A. Taylor.  All rights reserved.
00003 
00004     Redistribution and use in source and binary forms, with or without
00005     modification, are permitted provided that the following conditions are met:
00006 
00007     * Redistributions of source code must retain the above copyright notice,
00008       this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice,
00010       this list of conditions and the following disclaimer in the documentation
00011       and/or other materials provided with the distribution.
00012     * Neither the name of LibCat nor the names of its contributors may be used
00013       to endorse or promote products derived from this software without
00014       specific prior written permission.
00015 
00016     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00020     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026     POSSIBILITY OF SUCH DAMAGE.
00027 */
00028 
00029 #ifndef CAT_SOCKETS_HPP
00030 #define CAT_SOCKETS_HPP
00031 
00032 #include <cat/Platform.hpp>
00033 #include <string>
00034 
00035 #if defined(CAT_OS_WINDOWS)
00036 # include <WS2tcpip.h>
00037 #else
00038 # include <unistd.h>
00039 #endif
00040 
00041 #define CAT_IP4_LOOPBACK "127.0.0.1"
00042 #define CAT_IP6_LOOPBACK "::1"
00043 
00044 namespace cat {
00045 
00046 
00048 
00049 #if defined(CAT_OS_WINDOWS)
00050     typedef SOCKET Socket;
00051     CAT_INLINE bool CloseSocket(Socket s) { return !closesocket(s); }
00052 #else
00053     typedef int Socket;
00054     static const Socket INVALID_SOCKET = -1;
00055     static const int SOCKET_ERROR = -1;
00056     CAT_INLINE bool CloseSocket(Socket s) { return !close(s); }
00057 #endif
00058 
00059 typedef u16 Port;
00060 
00061 #pragma pack(push)
00062 #pragma pack(1)
00063 
00064 // Wrapper for IPv4 and IPv6 addresses
00065 class NetAddr
00066 {
00067     union
00068     {
00069         u8 v6_bytes[16];
00070         u16 v6_words[8];
00071         u64 v6[2];
00072         struct {
00073             u32 v4;
00074             u32 v4_padding[3];
00075         };
00076     } _ip; // Network order
00077 
00078     union
00079     {
00080         u32 _valid;
00081         struct {
00082             Port _port; // Host order
00083             u16 _family; // Host order
00084         };
00085     };
00086 
00087 public:
00088     static const int IP4_BYTES = 4;
00089     static const int IP6_BYTES = 16;
00090 
00091     typedef sockaddr_in6 SockAddr;
00092 
00093 public:
00094     CAT_INLINE NetAddr() {}
00095     NetAddr(const char *ip_str, Port port = 0);
00096     NetAddr(const sockaddr_in6 &addr);
00097     NetAddr(const sockaddr_in &addr);
00098     NetAddr(const sockaddr *addr);
00099     NetAddr(int a, int b, int c, int d, Port port = 0);
00100 
00101 public:
00102     NetAddr(const NetAddr &addr);
00103     NetAddr &operator=(const NetAddr &addr);
00104 
00105 public:
00106     bool Wrap(const sockaddr_in6 &addr);
00107     bool Wrap(const sockaddr_in &addr);
00108     bool Wrap(const sockaddr *addr);
00109 
00110 public:
00111     // Promote an IPv4 address to an IPv6 address if needed
00112     bool PromoteTo6();
00113 
00114     // Demote an IPv6 address to an IPv4 address if possible,
00115     // otherwise marks address as invalid and returns false
00116     bool DemoteTo4();
00117 
00118     CAT_INLINE bool Convert(bool To6) { if (To6) return PromoteTo6(); else return DemoteTo4(); }
00119 
00120 public:
00121     CAT_INLINE bool Valid() const { return _valid != 0; }
00122     CAT_INLINE bool Is6() const { return _family == AF_INET6; }
00123 
00124     CAT_INLINE const u32 GetIP4() const { return _ip.v4; }
00125     CAT_INLINE const u64 *GetIP6() const { return _ip.v6; }
00126 
00127     CAT_INLINE Port GetPort() const { return _port; }
00128     CAT_INLINE void SetPort(Port port) { _port = port; }
00129 
00130     // Mark the address as invalid
00131     CAT_INLINE void Invalidate() { _valid = 0; }
00132 
00133 public:
00134     bool EqualsIPOnly(const NetAddr &addr) const;
00135     bool operator==(const NetAddr &addr) const;
00136     bool operator!=(const NetAddr &addr) const;
00137 
00138 public:
00139     // To validate external input; don't want clients connecting
00140     // to their local network instead of the actual game server.
00141     bool IsInternetRoutable();
00142 
00143     // Returns true if the address is routable on local network or Internet.
00144     // Returns false if the address is IPv4 multicast, loopback, or weird.
00145     bool IsRoutable();
00146 
00147 public:
00148     bool SetFromString(const char *ip_str, Port port = 0);
00149     std::string IPToString() const;
00150 
00151     bool SetFromRawIP(const u8 *ip_binary, int bytes);
00152     bool SetFromDotDecimals(int a, int b, int c, int d, Port port = 0);
00153 
00154 public:
00155     bool Unwrap(SockAddr &addr, int &addr_len, bool PromoteToIP6 = false) const;
00156 };
00157 
00158 #pragma pack(pop)
00159 
00160 
00162 
00163 // Run startup and cleanup functions needed under some OS
00164 bool StartupSockets(); // returns false on error
00165 void CleanupSockets();
00166 
00167 // inout_OnlyIPv4: Indicates that only IPv4 is requested by caller
00168 // Sets OnlyIPv4 if IPv6 will be unsupported
00169 // Returns true on success
00170 bool CreateSocket(int type, int protocol, bool SupportIPv4, Socket &out_s, bool &inout_OnlyIPv4);
00171 
00172 // Returns true on success
00173 bool NetBind(Socket s, Port port, bool OnlyIPv4);
00174 
00175 // Returns 0 on failure
00176 Port GetBoundPort(Socket s);
00177 
00178 
00180 
00181 // Returns a string describing the last error from Winsock2 API
00182 std::string SocketGetLastErrorString();
00183 std::string SocketGetErrorString(int code);
00184 
00185 
00186 } // namespace cat
00187 
00188 #endif // CAT_SOCKETS_HPP

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net