1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/private/sckaddr.h
3 // Purpose: wxSockAddressImpl
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 #ifndef _WX_PRIVATE_SOCKADDR_H_
11 #define _WX_PRIVATE_SOCKADDR_H_
14 #include "wx/msw/wrapwin.h"
19 #elif defined(__VMS__)
24 u_char sun_len
; /* sockaddr len including null */
25 u_char sun_family
; /* AF_UNIX */
26 char sun_path
[108]; /* path name (gag) */
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
36 #include <stdlib.h> // for calloc()
38 // this is a wrapper for sockaddr_storage if it's available or just sockaddr
40 union wxSockAddressStorage
43 sockaddr_storage addr_storage
;
48 // ----------------------------------------------------------------------------
49 // helpers for wxSockAddressImpl
50 // ----------------------------------------------------------------------------
52 // helper class mapping sockaddr_xxx types to corresponding AF_XXX values
54 // FIXME-VC6: we could leave the template undefined if not for VC6 which
55 // absolutely does need to have a generic version defining the
56 // template "interface" to compile the code below
57 template <class T
> struct AddressFamily
{ enum { value
= AF_UNSPEC
}; };
59 template <> struct AddressFamily
<sockaddr_in
> { enum { value
= AF_INET
}; };
62 template <> struct AddressFamily
<sockaddr_in6
> { enum { value
= AF_INET6
}; };
65 #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
66 template <> struct AddressFamily
<sockaddr_un
> { enum { value
= AF_UNIX
}; };
67 #endif // wxHAS_UNIX_DOMAIN_SOCKETS
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 // Represents a socket endpoint, e.g. an (address, port) pair for PF_INET
74 // sockets. It can be initialized from an existing sockaddr struct and also
75 // provides access to sockaddr stored internally so that it can be easily used
76 // with e.g. connect(2).
78 // This class also performs (synchronous, hence potentially long) name lookups
79 // if necessary, i.e. if the host name strings don't contain addresses in
80 // numerical form (quad dotted for IPv4 or standard hexadecimal for IPv6).
81 // Notice that internally the potentially Unicode host names are encoded as
82 // UTF-8 before being passed to the lookup function but the host names should
83 // really be ASCII anyhow.
84 class wxSockAddressImpl
87 // as this is passed to socket() it should be a PF_XXX and not AF_XXX (even
88 // though they're the same in practice)
91 FAMILY_INET
= PF_INET
,
93 FAMILY_INET6
= PF_INET6
,
95 #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
96 FAMILY_UNIX
= PF_UNIX
,
98 FAMILY_UNSPEC
= PF_UNSPEC
101 // default ctor creates uninitialized object, use one of CreateXXX() below
107 // ctor from an existing sockaddr
108 wxSockAddressImpl(const sockaddr
& addr
, int len
)
110 switch ( addr
.sa_family
)
116 #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
119 m_family
= static_cast<Family
>(addr
.sa_family
);
123 wxFAIL_MSG( "unsupported socket address family" );
128 InitFromSockaddr(addr
, len
);
131 // copy ctor and assignment operators
132 wxSockAddressImpl(const wxSockAddressImpl
& other
)
134 InitFromOther(other
);
137 wxSockAddressImpl
& operator=(const wxSockAddressImpl
& other
)
142 InitFromOther(other
);
147 // dtor frees the memory used by m_addr
154 // reset the address to the initial uninitialized state
162 // initialize the address to be of specific address family, it must be
163 // currently uninitialized (you may call Clear() to achieve this)
166 #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
168 #endif // wxHAS_UNIX_DOMAIN_SOCKETS
169 void Create(Family family
)
183 #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
187 #endif // wxHAS_UNIX_DOMAIN_SOCKETS
190 wxFAIL_MSG( "unsupported socket address family" );
195 Family
GetFamily() const { return m_family
; }
196 bool Is(Family family
) const { return m_family
== family
; }
197 bool IsOk() const { return m_family
!= FAMILY_UNSPEC
; }
198 const sockaddr
*GetAddr() const { return m_addr
; }
199 sockaddr
*GetWritableAddr() { return m_addr
; }
200 int GetLen() const { return m_len
; }
202 // accessors for INET or INET6 address families
204 #define CALL_IPV4_OR_6(func, args) \
205 Is(FAMILY_INET6) ? func##6(args) : func##4(args)
206 #define CALL_IPV4_OR_6_VOID(func) \
207 Is(FAMILY_INET6) ? func##6() : func##4()
209 #define CALL_IPV4_OR_6(func, args) func##4(args)
210 #define CALL_IPV4_OR_6_VOID(func) func##4()
211 #endif // IPv6 support on/off
213 wxString
GetHostName() const;
214 bool SetHostName(const wxString
& name
)
216 return CALL_IPV4_OR_6(SetHostName
, (name
));
219 wxUint16
GetPort() const { return CALL_IPV4_OR_6_VOID(GetPort
); }
220 bool SetPort(wxUint16 port
) { return CALL_IPV4_OR_6(SetPort
, (port
)); }
221 bool SetPortName(const wxString
& name
, const char *protocol
);
223 bool SetToAnyAddress() { return CALL_IPV4_OR_6_VOID(SetToAnyAddress
); }
225 #undef CALL_IPV4_OR_6
227 // accessors for INET addresses only
228 bool GetHostAddress(wxUint32
*address
) const;
229 bool SetHostAddress(wxUint32 address
);
231 bool SetToBroadcastAddress() { return SetHostAddress(INADDR_BROADCAST
); }
233 // accessors for INET6 addresses only
235 bool GetHostAddress(in6_addr
*address
) const;
236 bool SetHostAddress(const in6_addr
& address
);
239 #ifdef wxHAS_UNIX_DOMAIN_SOCKETS
240 // methods valid for Unix address family addresses only
241 bool SetPath(const wxString
& path
);
242 wxString
GetPath() const;
243 #endif // wxHAS_UNIX_DOMAIN_SOCKETS
246 void DoAlloc(int len
)
248 m_addr
= static_cast<sockaddr
*>(calloc(1, len
));
252 // FIXME-VC6: VC6 doesn't grok Foo<T>() call syntax so we need the extra
253 // dummy parameter of type T, use the macros in sckaddr.cpp to
260 return reinterpret_cast<T
*>(m_addr
);
266 wxCHECK_MSG( static_cast<int>(m_family
) == AddressFamily
<T
>::value
,
268 "socket address family mismatch" );
270 return reinterpret_cast<T
*>(m_addr
);
275 m_family
= FAMILY_UNSPEC
;
280 void InitFromSockaddr(const sockaddr
& addr
, int len
)
283 memcpy(m_addr
, &addr
, len
);
286 void InitFromOther(const wxSockAddressImpl
& other
)
288 m_family
= other
.m_family
;
292 InitFromSockaddr(*other
.m_addr
, other
.m_len
);
294 else // no address to copy
301 // IPv4/6 implementations of public functions
302 bool SetHostName4(const wxString
& name
);
304 bool SetPort4(wxUint16 port
);
305 wxUint16
GetPort4() const;
307 bool SetToAnyAddress4() { return SetHostAddress(INADDR_ANY
); }
310 bool SetHostName6(const wxString
& name
);
312 bool SetPort6(wxUint16 port
);
313 wxUint16
GetPort6() const;
315 bool SetToAnyAddress6();
323 #endif // _WX_PRIVATE_SOCKADDR_H_