sckaddr.h 8.8 KB

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