aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/arch/IArchNetwork.h
blob: b859506166df66cb05fbd6722ba5d2f74e48aeda (plain) (blame)
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
/*
 * barrier -- mouse and keyboard sharing utility
 * Copyright (C) 2012-2016 Symless Ltd.
 * Copyright (C) 2002 Chris Schoeneman
 * 
 * This package is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * found in the file LICENSE that should have accompanied this file.
 * 
 * This package is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "common/IInterface.h"
#include "common/stdstring.h"

class ArchThreadImpl;
typedef ArchThreadImpl* ArchThread;

/*!      
\class ArchSocketImpl
\brief Internal socket data.
An architecture dependent type holding the necessary data for a socket.
*/
class ArchSocketImpl;

/*!      
\var ArchSocket
\brief Opaque socket type.
An opaque type representing a socket.
*/
typedef ArchSocketImpl* ArchSocket;

/*!      
\class ArchNetAddressImpl
\brief Internal network address data.
An architecture dependent type holding the necessary data for a network
address.
*/
class ArchNetAddressImpl;

/*!      
\var ArchNetAddress
\brief Opaque network address type.
An opaque type representing a network address.
*/
typedef ArchNetAddressImpl* ArchNetAddress;

//! Interface for architecture dependent networking
/*!
This interface defines the networking operations required by
barrier.  Each architecture must implement this interface.
*/
class IArchNetwork : public IInterface {
public:
    //! Supported address families
    enum EAddressFamily {
        kUNKNOWN,
        kINET,
        kINET6,
    };

    //! Supported socket types
    enum ESocketType {
        kDGRAM,
        kSTREAM
    };

    //! Events for \c poll()
    /*!
    Events for \c poll() are bitmasks and can be combined using the
    bitwise operators.
    */
    enum {
        kPOLLIN   = 1,        //!< Socket is readable
        kPOLLOUT  = 2,        //!< Socket is writable
        kPOLLERR  = 4,        //!< The socket is in an error state
        kPOLLNVAL = 8        //!< The socket is invalid
    };

    //! A socket query for \c poll()
    class PollEntry {
    public:
        //! The socket to query
        ArchSocket        m_socket;

        //! The events to query for
        /*!
        The events to query for can be any combination of kPOLLIN and
        kPOLLOUT.
        */
        unsigned short    m_events;

        //! The result events
        unsigned short    m_revents;
    };

    //! @name manipulators
    //@{

    //! Create a new socket
    /*!
    The socket is an opaque data type.
    */
    virtual ArchSocket    newSocket(EAddressFamily, ESocketType) = 0;

    //! Copy a socket object
    /*!
    Returns a reference to to socket referred to by \c s.
    */
    virtual ArchSocket    copySocket(ArchSocket s) = 0;

    //! Release a socket reference
    /*!
    Deletes the given socket object.  This does not destroy the socket
    the object referred to until there are no remaining references for
    the socket.
    */
    virtual void        closeSocket(ArchSocket s) = 0;

    //! Close socket for further reads
    /*!
    Calling this disallows future reads on socket \c s.
    */
    virtual void        closeSocketForRead(ArchSocket s) = 0;

    //! Close socket for further writes
    /*!
    Calling this disallows future writes on socket \c s.
    */
    virtual void        closeSocketForWrite(ArchSocket s) = 0;

    //! Bind socket to address
    /*!
    Binds socket \c s to the address \c addr.
    */
    virtual void        bindSocket(ArchSocket s, ArchNetAddress addr) = 0;

    //! Listen for connections on socket
    /*!
    Causes the socket \c s to begin listening for incoming connections.
    */
    virtual void        listenOnSocket(ArchSocket s) = 0;

    //! Accept connection on socket
    /*!
    Accepts a connection on socket \c s, returning a new socket for the
    connection and filling in \c addr with the address of the remote
    end.  \c addr may be NULL if the remote address isn't required.
    The original socket \c s is unaffected and remains in the listening
    state.  The new socket shares most of the properties of \c s except
    it's not in the listening state and it's connected.  Returns NULL
    if there are no pending connection requests.
    */
    virtual ArchSocket    acceptSocket(ArchSocket s, ArchNetAddress* addr) = 0;

    //! Connect socket
    /*!
    Connects the socket \c s to the remote address \c addr.  Returns
    true if the connection succeed immediately, false if the connection
    is in progress, and throws if the connection failed    immediately.
    If it returns false, \c pollSocket() can be used to wait on the
    socket for writing to detect when the connection finally succeeds
    or fails.
    */
    virtual bool        connectSocket(ArchSocket s, ArchNetAddress addr) = 0;

    //! Check socket state
    /*!
    Tests the state of \c num sockets for readability and/or writability.
    Waits up to \c timeout seconds for some socket to become readable
    and/or writable (or indefinitely if \c timeout < 0).  Returns the
    number of sockets that were readable (if readability was being
    queried) or writable (if writablility was being queried) and sets
    the \c m_revents members of the entries.  \c kPOLLERR and \c kPOLLNVAL
    are set in \c m_revents as appropriate.  If a socket indicates
    \c kPOLLERR then \c throwErrorOnSocket() can be used to determine
    the type of error.  Returns 0 immediately regardless of the \c timeout
    if no valid sockets are selected for testing.

    (Cancellation point)
    */
    virtual int            pollSocket(PollEntry[], int num, double timeout) = 0;

    //! Unblock thread in pollSocket()
    /*!
    Cause a thread that's in a pollSocket() call to return.  This
    call may return before the thread is unblocked.  If the thread is
    not in a pollSocket() call this call has no effect.
    */
    virtual void        unblockPollSocket(ArchThread thread) = 0;

    //! Read data from socket
    /*!
    Read up to \c len bytes from socket \c s in \c buf and return the
    number of bytes read.  The number of bytes can be less than \c len
    if not enough data is available.  Returns 0 if the remote end has
    disconnected and/or there is no more queued received data.
    */
    virtual size_t        readSocket(ArchSocket s, void* buf, size_t len) = 0;

    //! Write data from socket
    /*!
    Write up to \c len bytes to socket \c s from \c buf and return the
    number of bytes written.  The number of bytes can be less than
    \c len if the remote end disconnected or the internal buffers fill
    up.
    */
    virtual size_t        writeSocket(ArchSocket s,
                            const void* buf, size_t len) = 0;

    //! Check error on socket
    /*!
    If the socket \c s is in an error state then throws an appropriate
    XArchNetwork exception.
    */
    virtual void        throwErrorOnSocket(ArchSocket s) = 0;

    //! Turn Nagle algorithm on or off on socket
    /*!
    Set socket to send messages immediately (true) or to collect small
    messages into one packet (false).  Returns the previous state.
    */
    virtual bool        setNoDelayOnSocket(ArchSocket, bool noDelay) = 0;

    //! Turn address reuse on or off on socket
    /*!
    Allows the address this socket is bound to to be reused while in the
    TIME_WAIT state.  Returns the previous state.
    */
    virtual bool        setReuseAddrOnSocket(ArchSocket, bool reuse) = 0;

    //! Return local host's name
    virtual std::string        getHostName() = 0;

    //! Create an "any" network address
    virtual ArchNetAddress    newAnyAddr(EAddressFamily) = 0;

    //! Copy a network address
    virtual ArchNetAddress    copyAddr(ArchNetAddress) = 0;

    //! Convert a name to a network address
    virtual ArchNetAddress    nameToAddr(const std::string&) = 0;

    //! Destroy a network address
    virtual void            closeAddr(ArchNetAddress) = 0;

    //! Convert an address to a host name
    virtual std::string        addrToName(ArchNetAddress) = 0;

    //! Convert an address to a string
    virtual std::string        addrToString(ArchNetAddress) = 0;

    //! Get an address's family
    virtual EAddressFamily    getAddrFamily(ArchNetAddress) = 0;

    //! Set the port of an address
    virtual void            setAddrPort(ArchNetAddress, int port) = 0;

    //! Get the port of an address
    virtual int                getAddrPort(ArchNetAddress) = 0;

    //! Test addresses for equality
    virtual bool            isEqualAddr(ArchNetAddress, ArchNetAddress) = 0;

    //! Test for the "any" address
    /*!
    Returns true if \c addr is the "any" address.  \c newAnyAddr()
    returns an "any" address.
    */
    virtual bool            isAnyAddr(ArchNetAddress addr) = 0;

    //@}

    virtual void init() = 0;
};