~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to include/wx/private/sckaddr.h

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

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