File: sckaddr.h

package info (click to toggle)
wxpython3.0 3.0.2.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 482,760 kB
  • ctags: 518,293
  • sloc: cpp: 2,127,226; python: 294,045; makefile: 51,942; ansic: 19,033; sh: 3,013; xml: 1,629; perl: 17
file content (323 lines) | stat: -rw-r--r-- 8,996 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
///////////////////////////////////////////////////////////////////////////////
// Name:        wx/private/sckaddr.h
// Purpose:     wxSockAddressImpl
// Author:      Vadim Zeitlin
// Created:     2008-12-28
// Copyright:   (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence:     wxWindows licence
///////////////////////////////////////////////////////////////////////////////

#ifndef _WX_PRIVATE_SOCKADDR_H_
#define _WX_PRIVATE_SOCKADDR_H_

#ifdef __WINDOWS__
    #include "wx/msw/wrapwin.h"

    #if wxUSE_IPV6
        #include <ws2tcpip.h>
    #endif
#elif defined(__VMS__)
    #include <socket.h>

    struct sockaddr_un
    {
        u_char  sun_len;        /* sockaddr len including null */
        u_char  sun_family;     /* AF_UNIX */
        char    sun_path[108];  /* path name (gag) */
    };
    #include <in.h>
#else // generic Unix
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/un.h>
#endif // platform

#include <stdlib.h> // for calloc()

// this is a wrapper for sockaddr_storage if it's available or just sockaddr
// otherwise
union wxSockAddressStorage
{
#if wxUSE_IPV6
    sockaddr_storage addr_storage;
#endif
    sockaddr addr;
};

// ----------------------------------------------------------------------------
// helpers for wxSockAddressImpl
// ----------------------------------------------------------------------------

// helper class mapping sockaddr_xxx types to corresponding AF_XXX values
//
// FIXME-VC6: we could leave the template undefined if not for VC6 which
//            absolutely does need to have a generic version defining the
//            template "interface" to compile the code below
template <class T> struct AddressFamily { enum { value = AF_UNSPEC }; };

template <> struct AddressFamily<sockaddr_in> { enum { value = AF_INET }; };

#if wxUSE_IPV6
template <> struct AddressFamily<sockaddr_in6> { enum { value = AF_INET6 }; };
#endif // wxUSE_IPV6

#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
template <> struct AddressFamily<sockaddr_un> { enum { value = AF_UNIX }; };
#endif // wxHAS_UNIX_DOMAIN_SOCKETS

// ----------------------------------------------------------------------------
// wxSockAddressImpl
// ----------------------------------------------------------------------------

// Represents a socket endpoint, e.g. an (address, port) pair for PF_INET
// sockets. It can be initialized from an existing sockaddr struct and also
// provides access to sockaddr stored internally so that it can be easily used
// with e.g. connect(2).
//
// This class also performs (synchronous, hence potentially long) name lookups
// if necessary, i.e. if the host name strings don't contain addresses in
// numerical form (quad dotted for IPv4 or standard hexadecimal for IPv6).
// Notice that internally the potentially Unicode host names are encoded as
// UTF-8 before being passed to the lookup function but the host names should
// really be ASCII anyhow.
class wxSockAddressImpl
{
public:
    // as this is passed to socket() it should be a PF_XXX and not AF_XXX (even
    // though they're the same in practice)
    enum Family
    {
        FAMILY_INET = PF_INET,
#if wxUSE_IPV6
        FAMILY_INET6 = PF_INET6,
#endif
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
        FAMILY_UNIX = PF_UNIX,
#endif
        FAMILY_UNSPEC = PF_UNSPEC
    };

    // default ctor creates uninitialized object, use one of CreateXXX() below
    wxSockAddressImpl()
    {
        InitUnspec();
    }

    // ctor from an existing sockaddr
    wxSockAddressImpl(const sockaddr& addr, int len)
    {
        switch ( addr.sa_family )
        {
            case PF_INET:
#if wxUSE_IPV6
            case PF_INET6:
#endif
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
            case PF_UNIX:
#endif
                m_family = static_cast<Family>(addr.sa_family);
                break;

            default:
                wxFAIL_MSG( "unsupported socket address family" );
                InitUnspec();
                return;
        }

        InitFromSockaddr(addr, len);
    }

    // copy ctor and assignment operators
    wxSockAddressImpl(const wxSockAddressImpl& other)
    {
        InitFromOther(other);
    }

    wxSockAddressImpl& operator=(const wxSockAddressImpl& other)
    {
        if (this != &other)
        {
            free(m_addr);
            InitFromOther(other);
        }
        return *this;
    }

    // dtor frees the memory used by m_addr
    ~wxSockAddressImpl()
    {
        free(m_addr);
    }


    // reset the address to the initial uninitialized state
    void Clear()
    {
        free(m_addr);

        InitUnspec();
    }

    // initialize the address to be of specific address family, it must be
    // currently uninitialized (you may call Clear() to achieve this)
    void CreateINET();
    void CreateINET6();
#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
    void CreateUnix();
#endif // wxHAS_UNIX_DOMAIN_SOCKETS
    void Create(Family family)
    {
        switch ( family )
        {
            case FAMILY_INET:
                CreateINET();
                break;

#if wxUSE_IPV6
            case FAMILY_INET6:
                CreateINET6();
                break;
#endif // wxUSE_IPV6

#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
            case FAMILY_UNIX:
                CreateUnix();
                break;
#endif // wxHAS_UNIX_DOMAIN_SOCKETS

            default:
                wxFAIL_MSG( "unsupported socket address family" );
        }
    }

    // simple accessors
    Family GetFamily() const { return m_family; }
    bool Is(Family family) const { return m_family == family; }
    bool IsOk() const { return m_family != FAMILY_UNSPEC; }
    const sockaddr *GetAddr() const { return m_addr; }
    sockaddr *GetWritableAddr() { return m_addr; }
    int GetLen() const { return m_len; }

    // accessors for INET or INET6 address families
#if wxUSE_IPV6
    #define CALL_IPV4_OR_6(func, args) \
        Is(FAMILY_INET6) ? func##6(args) : func##4(args)
    #define CALL_IPV4_OR_6_VOID(func) \
        Is(FAMILY_INET6) ? func##6() : func##4()
#else
    #define CALL_IPV4_OR_6(func, args) func##4(args)
    #define CALL_IPV4_OR_6_VOID(func) func##4()
#endif // IPv6 support on/off

    wxString GetHostName() const;
    bool SetHostName(const wxString& name)
    {
        return CALL_IPV4_OR_6(SetHostName, (name));
    }

    wxUint16 GetPort() const { return CALL_IPV4_OR_6_VOID(GetPort); }
    bool SetPort(wxUint16 port) { return CALL_IPV4_OR_6(SetPort, (port)); }
    bool SetPortName(const wxString& name, const char *protocol);

    bool SetToAnyAddress() { return CALL_IPV4_OR_6_VOID(SetToAnyAddress); }

#undef CALL_IPV4_OR_6

    // accessors for INET addresses only
    bool GetHostAddress(wxUint32 *address) const;
    bool SetHostAddress(wxUint32 address);

    bool SetToBroadcastAddress() { return SetHostAddress(INADDR_BROADCAST); }

    // accessors for INET6 addresses only
#if wxUSE_IPV6
    bool GetHostAddress(in6_addr *address) const;
    bool SetHostAddress(const in6_addr& address);
#endif // wxUSE_IPV6

#ifdef wxHAS_UNIX_DOMAIN_SOCKETS
    // methods valid for Unix address family addresses only
    bool SetPath(const wxString& path);
    wxString GetPath() const;
#endif // wxHAS_UNIX_DOMAIN_SOCKETS

private:
    void DoAlloc(int len)
    {
        m_addr = static_cast<sockaddr *>(calloc(1, len));
        m_len = len;
    }

    // FIXME-VC6: VC6 doesn't grok Foo<T>() call syntax so we need the extra
    //            dummy parameter of type T, use the macros in sckaddr.cpp to
    //            hide it
    template <class T>
    T *Alloc(T *)
    {
        DoAlloc(sizeof(T));

        return reinterpret_cast<T *>(m_addr);
    }

    template <class T>
    T *Get(T *) const
    {
        wxCHECK_MSG( static_cast<int>(m_family) == AddressFamily<T>::value,
                     NULL,
                     "socket address family mismatch" );

        return reinterpret_cast<T *>(m_addr);
    }

    void InitUnspec()
    {
        m_family = FAMILY_UNSPEC;
        m_addr = NULL;
        m_len = 0;
    }

    void InitFromSockaddr(const sockaddr& addr, int len)
    {
        DoAlloc(len);
        memcpy(m_addr, &addr, len);
    }

    void InitFromOther(const wxSockAddressImpl& other)
    {
        m_family = other.m_family;

        if ( other.m_addr )
        {
            InitFromSockaddr(*other.m_addr, other.m_len);
        }
        else // no address to copy
        {
            m_addr = NULL;
            m_len = 0;
        }
    }

    // IPv4/6 implementations of public functions
    bool SetHostName4(const wxString& name);

    bool SetPort4(wxUint16 port);
    wxUint16 GetPort4() const;

    bool SetToAnyAddress4() { return SetHostAddress(INADDR_ANY); }

#if wxUSE_IPV6
    bool SetHostName6(const wxString& name);

    bool SetPort6(wxUint16 port);
    wxUint16 GetPort6() const;

    bool SetToAnyAddress6();
#endif // wxUSE_IPV6

    Family m_family;
    sockaddr *m_addr;
    int m_len;
};

#endif // _WX_PRIVATE_SOCKADDR_H_