PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Extras/wxWidgets-2.9.0/include/wx/private/sckaddr.h

http://dynamica.googlecode.com/
C Header | 323 lines | 216 code | 56 blank | 51 comment | 7 complexity | 137760d628092f7643995f38d99ac964 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-3.0
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/private/sockaddr.h
  3. // Purpose: wxSockAddressImpl
  4. // Author: Vadim Zeitlin
  5. // Created: 2008-12-28
  6. // RCS-ID: $Id: sckaddr.h 60571 2009-05-09 16:04:00Z VZ $
  7. // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
  8. // Licence: wxWindows licence
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #ifndef _WX_PRIVATE_SOCKADDR_H_
  11. #define _WX_PRIVATE_SOCKADDR_H_
  12. #ifdef __WXMSW__
  13. #include "wx/msw/wrapwin.h"
  14. #if wxUSE_IPV6
  15. #include <ws2tcpip.h>
  16. #endif
  17. #elif defined(__VMS__)
  18. #include <socket.h>
  19. struct sockaddr_un
  20. {
  21. u_char sun_len; /* sockaddr len including null */
  22. u_char sun_family; /* AF_UNIX */
  23. char sun_path[108]; /* path name (gag) */
  24. };
  25. #include <in.h>
  26. #else // generic Unix
  27. #include <sys/types.h>
  28. #include <sys/socket.h>
  29. #include <netinet/in.h>
  30. #include <sys/un.h>
  31. #endif // platform
  32. #include <stdlib.h> // for calloc()
  33. // this is a wrapper for sockaddr_storage if it's available or just sockaddr
  34. // otherwise
  35. union wxSockAddressStorage
  36. {
  37. #if wxUSE_IPV6
  38. sockaddr_storage addr_storage;
  39. #endif
  40. sockaddr addr;
  41. };
  42. // ----------------------------------------------------------------------------
  43. // helpers for wxSockAddressImpl
  44. // ----------------------------------------------------------------------------
  45. // helper class mapping sockaddr_xxx types to corresponding AF_XXX values
  46. //
  47. // FIXME-VC6: we could leave the template undefined if not for VC6 which
  48. // absolutely does need to have a generic version defining the
  49. // template "interface" to compile the code below
  50. template <class T> struct AddressFamily { enum { value = AF_UNSPEC }; };
  51. template <> struct AddressFamily<sockaddr_in> { enum { value = AF_INET }; };
  52. #if wxUSE_IPV6
  53. template <> struct AddressFamily<sockaddr_in6> { enum { value = AF_INET6 }; };
  54. #endif // wxUSE_IPV6
  55. #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
  56. template <> struct AddressFamily<sockaddr_un> { enum { value = AF_UNIX }; };
  57. #endif // wxHAS_UNIX_DOMAIN_SOCKETS
  58. // ----------------------------------------------------------------------------
  59. // wxSockAddressImpl
  60. // ----------------------------------------------------------------------------
  61. // Represents a socket endpoint, e.g. an (address, port) pair for PF_INET
  62. // sockets. It can be initialized from an existing sockaddr struct and also
  63. // provides access to sockaddr stored internally so that it can be easily used
  64. // with e.g. connect(2).
  65. //
  66. // This class also performs (synchronous, hence potentially long) name lookups
  67. // if necessary, i.e. if the host name strings don't contain addresses in
  68. // numerical form (quad dotted for IPv4 or standard hexadecimal for IPv6).
  69. // Notice that internally the potentially Unicode host names are encoded as
  70. // UTF-8 before being passed to the lookup function but the host names should
  71. // really be ASCII anyhow.
  72. class wxSockAddressImpl
  73. {
  74. public:
  75. // as this is passed to socket() it should be a PF_XXX and not AF_XXX (even
  76. // though they're the same in practice)
  77. enum Family
  78. {
  79. FAMILY_INET = PF_INET,
  80. #if wxUSE_IPV6
  81. FAMILY_INET6 = PF_INET6,
  82. #endif
  83. #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
  84. FAMILY_UNIX = PF_UNIX,
  85. #endif
  86. FAMILY_UNSPEC = PF_UNSPEC
  87. };
  88. // default ctor creates uninitialized object, use one of CreateXXX() below
  89. wxSockAddressImpl()
  90. {
  91. InitUnspec();
  92. }
  93. // ctor from an existing sockaddr
  94. wxSockAddressImpl(const sockaddr& addr, int len)
  95. {
  96. switch ( addr.sa_family )
  97. {
  98. case PF_INET:
  99. #if wxUSE_IPV6
  100. case PF_INET6:
  101. #endif
  102. #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
  103. case PF_UNIX:
  104. #endif
  105. m_family = static_cast<Family>(addr.sa_family);
  106. break;
  107. default:
  108. wxFAIL_MSG( "unsupported socket address family" );
  109. InitUnspec();
  110. return;
  111. }
  112. InitFromSockaddr(addr, len);
  113. }
  114. // copy ctor and assignment operators
  115. wxSockAddressImpl(const wxSockAddressImpl& other)
  116. {
  117. InitFromOther(other);
  118. }
  119. wxSockAddressImpl& operator=(const wxSockAddressImpl& other)
  120. {
  121. free(m_addr);
  122. InitFromOther(other);
  123. return *this;
  124. }
  125. // dtor frees the memory used by m_addr
  126. ~wxSockAddressImpl()
  127. {
  128. free(m_addr);
  129. }
  130. // reset the address to the initial uninitialized state
  131. void Clear()
  132. {
  133. free(m_addr);
  134. InitUnspec();
  135. }
  136. // initialize the address to be of specific address family, it must be
  137. // currently uninitialized (you may call Clear() to achieve this)
  138. void CreateINET();
  139. void CreateINET6();
  140. #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
  141. void CreateUnix();
  142. #endif // wxHAS_UNIX_DOMAIN_SOCKETS
  143. void Create(Family family)
  144. {
  145. switch ( family )
  146. {
  147. case FAMILY_INET:
  148. CreateINET();
  149. break;
  150. #if wxUSE_IPV6
  151. case FAMILY_INET6:
  152. CreateINET6();
  153. break;
  154. #endif // wxUSE_IPV6
  155. #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
  156. case FAMILY_UNIX:
  157. CreateUnix();
  158. break;
  159. #endif // wxHAS_UNIX_DOMAIN_SOCKETS
  160. default:
  161. wxFAIL_MSG( "unsupported socket address family" );
  162. }
  163. }
  164. // simple accessors
  165. Family GetFamily() const { return m_family; }
  166. bool Is(Family family) const { return m_family == family; }
  167. bool IsOk() const { return m_family != FAMILY_UNSPEC; }
  168. const sockaddr *GetAddr() const { return m_addr; }
  169. sockaddr *GetWritableAddr() { return m_addr; }
  170. int GetLen() const { return m_len; }
  171. // accessors for INET or INET6 address families
  172. #if wxUSE_IPV6
  173. #define CALL_IPV4_OR_6(func, args) \
  174. Is(FAMILY_INET6) ? func##6(args) : func##4(args)
  175. #define CALL_IPV4_OR_6_VOID(func) \
  176. Is(FAMILY_INET6) ? func##6() : func##4()
  177. #else
  178. #define CALL_IPV4_OR_6(func, args) func##4(args)
  179. #define CALL_IPV4_OR_6_VOID(func) func##4()
  180. #endif // IPv6 support on/off
  181. wxString GetHostName() const;
  182. bool SetHostName(const wxString& name)
  183. {
  184. return CALL_IPV4_OR_6(SetHostName, (name));
  185. }
  186. wxUint16 GetPort() const { return CALL_IPV4_OR_6_VOID(GetPort); }
  187. bool SetPort(wxUint16 port) { return CALL_IPV4_OR_6(SetPort, (port)); }
  188. bool SetPortName(const wxString& name, const char *protocol);
  189. bool SetToAnyAddress() { return CALL_IPV4_OR_6_VOID(SetToAnyAddress); }
  190. #undef CALL_IPV4_OR_6
  191. // accessors for INET addresses only
  192. bool GetHostAddress(wxUint32 *address) const;
  193. bool SetHostAddress(wxUint32 address);
  194. bool SetToBroadcastAddress() { return SetHostAddress(INADDR_BROADCAST); }
  195. // accessors for INET6 addresses only
  196. #if wxUSE_IPV6
  197. bool GetHostAddress(in6_addr *address) const;
  198. bool SetHostAddress(const in6_addr& address);
  199. #endif // wxUSE_IPV6
  200. #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
  201. // methods valid for Unix address family addresses only
  202. bool SetPath(const wxString& path);
  203. wxString GetPath() const;
  204. #endif // wxHAS_UNIX_DOMAIN_SOCKETS
  205. private:
  206. void DoAlloc(int len)
  207. {
  208. m_addr = static_cast<sockaddr *>(calloc(1, len));
  209. m_len = len;
  210. }
  211. // FIXME-VC6: VC6 doesn't grok Foo<T>() call syntax so we need the extra
  212. // dummy parameter of type T, use the macros in sckaddr.cpp to
  213. // hide it
  214. template <class T>
  215. T *Alloc(T *)
  216. {
  217. DoAlloc(sizeof(T));
  218. return reinterpret_cast<T *>(m_addr);
  219. }
  220. template <class T>
  221. T *Get(T *) const
  222. {
  223. wxCHECK_MSG( static_cast<int>(m_family) == AddressFamily<T>::value,
  224. NULL,
  225. "socket address family mismatch" );
  226. return reinterpret_cast<T *>(m_addr);
  227. }
  228. void InitUnspec()
  229. {
  230. m_family = FAMILY_UNSPEC;
  231. m_addr = NULL;
  232. m_len = 0;
  233. }
  234. void InitFromSockaddr(const sockaddr& addr, int len)
  235. {
  236. DoAlloc(len);
  237. memcpy(m_addr, &addr, len);
  238. }
  239. void InitFromOther(const wxSockAddressImpl& other)
  240. {
  241. m_family = other.m_family;
  242. if ( other.m_addr )
  243. {
  244. InitFromSockaddr(*other.m_addr, other.m_len);
  245. }
  246. else // no address to copy
  247. {
  248. m_addr = NULL;
  249. m_len = 0;
  250. }
  251. }
  252. // IPv4/6 implementations of public functions
  253. bool SetHostName4(const wxString& name);
  254. bool SetPort4(wxUint16 port);
  255. wxUint16 GetPort4() const;
  256. bool SetToAnyAddress4() { return SetHostAddress(INADDR_ANY); }
  257. #if wxUSE_IPV6
  258. bool SetHostName6(const wxString& name);
  259. bool SetPort6(wxUint16 port);
  260. wxUint16 GetPort6() const;
  261. bool SetToAnyAddress6();
  262. #endif // wxUSE_IPV6
  263. Family m_family;
  264. sockaddr *m_addr;
  265. int m_len;
  266. };
  267. #endif // _WX_PRIVATE_SOCKADDR_H_