summaryrefslogtreecommitdiffstats
path: root/include/iprt/socket.h
blob: c7a572e7b102a42344a5cdd6a431e8d8d5e5dc9a (plain)
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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
/** @file
 * IPRT - Network Sockets.
 */

/*
 * Copyright (C) 2006-2022 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program 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 <https://www.gnu.org/licenses>.
 *
 * The contents of this file may alternatively be used under the terms
 * of the Common Development and Distribution License Version 1.0
 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
 * in the VirtualBox distribution, in which case the provisions of the
 * CDDL are applicable instead of those of the GPL.
 *
 * You may elect to license modified versions of this file under the
 * terms and conditions of either the GPL or the CDDL or both.
 *
 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
 */

#ifndef IPRT_INCLUDED_socket_h
#define IPRT_INCLUDED_socket_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif

#include <iprt/cdefs.h>
#include <iprt/types.h>
#include <iprt/thread.h>
#include <iprt/net.h>
#include <iprt/sg.h>

#ifdef IN_RING0
# error "There are no RTSocket APIs available Ring-0 Host Context!"
#endif


RT_C_DECLS_BEGIN

/** @defgroup grp_rt_socket RTSocket - Network Sockets
 * @ingroup grp_rt
 * @{
 */

/** Use the system default timeout for the connet attempt. */
#define RT_SOCKETCONNECT_DEFAULT_WAIT (RT_INDEFINITE_WAIT - 1)

/**
 * Retains a reference to the socket handle.
 *
 * @returns New reference count, UINT32_MAX on invalid handle (asserted).
 *
 * @param   hSocket         The socket handle.
 */
RTDECL(uint32_t) RTSocketRetain(RTSOCKET hSocket);

/**
 * Release a reference to the socket handle.
 *
 * When the reference count reaches zero, the socket handle is shut down and
 * destroyed.  This will not be graceful shutdown, use the protocol specific
 * close method if this is desired.
 *
 * @returns New reference count, UINT32_MAX on invalid handle (asserted).
 *
 * @param   hSocket         The socket handle.  The NIL handle is quietly
 *                          ignored and 0 is returned.
 */
RTDECL(uint32_t) RTSocketRelease(RTSOCKET hSocket);

/**
 * Shuts down the socket, close it and then release one handle reference.
 *
 * This is slightly different from RTSocketRelease which will first do the
 * shutting down and closing when the reference count reaches zero.
 *
 * @returns IPRT status code.
 * @param   hSocket         The socket handle.  NIL is ignored.
 *
 * @remarks This will not perform a graceful shutdown of the socket, it will
 *          just destroy it.  Use the protocol specific close method if this is
 *          desired.
 */
RTDECL(int) RTSocketClose(RTSOCKET hSocket);

/**
 * Creates an IPRT socket handle from a native one.
 *
 * Do NOT use the native handle after passing it to this function, IPRT owns it
 * and might even have closed upon a successful return.
 *
 * @returns IPRT status code.
 * @param   phSocket        Where to store the IPRT socket handle.
 * @param   uNative         The native handle.
 */
RTDECL(int) RTSocketFromNative(PRTSOCKET phSocket, RTHCINTPTR uNative);

/**
 * Gets the native socket handle.
 *
 * @returns The native socket handle or RTHCUINTPTR_MAX if not invalid.
 * @param   hSocket             The socket handle.
 */
RTDECL(RTHCUINTPTR) RTSocketToNative(RTSOCKET hSocket);

/**
 * Helper that ensures the correct inheritability of a socket.
 *
 * We're currently ignoring failures.
 *
 * @returns IPRT status code
 * @param   hSocket         The socket handle.
 * @param   fInheritable    The desired inheritability state.
 */
RTDECL(int) RTSocketSetInheritance(RTSOCKET hSocket, bool fInheritable);

/**
 * Parse Internet style addresses, getting a generic IPRT network address.
 *
 * @returns IPRT status code
 * @param   pszAddress      Name or IP address.  NULL or empty string (no
 *                          spaces) is taken to mean INADDR_ANY, which is
 *                          meaningful when binding a server socket for
 *                          instance.
 * @param   uPort           Port number (host byte order).
 * @param   pAddr           Where to return the generic IPRT network address.
 */
RTDECL(int) RTSocketParseInetAddress(const char *pszAddress, unsigned uPort, PRTNETADDR pAddr);

/**
 * Try resolve a host name, returning the first matching address.
 *
 * @returns IPRT status code.
 * @param   pszHost         Name or IP address to look up.
 * @param   pszAddress      Where to return the stringified address.
 * @param   pcbAddress      Input: The size of the @a pszResult buffer.
 *                          Output: size of the returned string.  This is set on
 *                          VERR_BUFFER_OVERFLOW and most other error statuses.
 * @param   penmAddrType    Input: Which kind of address to return. Valid values
 *                          are:
 *                              - RTNETADDRTYPE_IPV4 -> lookup AF_INET.
 *                              - RTNETADDRTYPE_IPV6 -> lookup AF_INET6.
 *                              - RTNETADDRTYPE_INVALID/NULL -> lookup anything.
 *                          Output: The type of address that is being returned.
 *                          Not modified on failure.
 */
RTDECL(int) RTSocketQueryAddressStr(const char *pszHost, char *pszAddress, size_t *pcbAddress, PRTNETADDRTYPE penmAddrType);

/**
 * Receive data from a socket.
 *
 * @returns IPRT status code.
 * @param   hSocket         The socket handle.
 * @param   pvBuffer        Where to put the data we read.
 * @param   cbBuffer        Read buffer size.
 * @param   pcbRead         Number of bytes read. If NULL the entire buffer
 *                          will be filled upon successful return. If not NULL a
 *                          partial read can be done successfully.
 */
RTDECL(int) RTSocketRead(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead);

/**
 * Receive data from a socket, including sender address. Mainly useful
 * for datagram sockets.
 *
 * @returns IPRT status code.
 * @param   hSocket         The socket handle.
 * @param   pvBuffer        Where to put the data we read.
 * @param   cbBuffer        Read buffer size.
 * @param   pcbRead         Number of bytes read. Must be non-NULL.
 * @param   pSrcAddr        Pointer to sender address buffer. May be NULL.
 */
RTDECL(int) RTSocketReadFrom(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead, PRTNETADDR pSrcAddr);

/**
 * Send data to a socket.
 *
 * @returns IPRT status code.
 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
 *
 * @param   hSocket         The socket handle.
 * @param   pvBuffer        Buffer to write data to socket.
 * @param   cbBuffer        How much to write.
 */
RTDECL(int) RTSocketWrite(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer);

/**
 * Send data to a socket, including destination address. Mainly useful
 * for datagram sockets.
 *
 * @returns IPRT status code.
 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
 *
 * @param   hSocket         The socket handle.
 * @param   pvBuffer        Buffer to write data to socket.
 * @param   cbBuffer        How much to write.
 * @param   pDstAddr        Pointer to destination address. May be NULL.
 */
RTDECL(int) RTSocketWriteTo(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, PCRTNETADDR pDstAddr);

/**
 * Checks if the socket is ready for reading (for I/O multiplexing).
 *
 * @returns IPRT status code.
 * @param   hSocket         The socket handle.
 * @param   cMillies        Number of milliseconds to wait for the socket.  Use
 *                          RT_INDEFINITE_WAIT to wait for ever.
 */
RTDECL(int) RTSocketSelectOne(RTSOCKET hSocket, RTMSINTERVAL cMillies);

/** @name Select events
 * @{ */
/** Readable without blocking. */
#define RTSOCKET_EVT_READ         RT_BIT_32(0)
/** Writable without blocking. */
#define RTSOCKET_EVT_WRITE        RT_BIT_32(1)
/** Error condition, hangup, exception or similar. */
#define RTSOCKET_EVT_ERROR        RT_BIT_32(2)
/** Mask of the valid bits. */
#define RTSOCKET_EVT_VALID_MASK   UINT32_C(0x00000007)
/** @} */

/**
 * Socket I/O multiplexing
 * Checks if the socket is ready for one of the given events.
 *
 * @returns iprt status code.
 * @param   hSocket         The Socket handle.
 * @param   fEvents         Event mask to wait for.
 * @param   pfEvents        Where to store the event mask on return.
 * @param   cMillies        Number of milliseconds to wait for the socket.  Use
 *                          RT_INDEFINITE_WAIT to wait for ever.
 */
RTR3DECL(int)  RTSocketSelectOneEx(RTSOCKET hSocket, uint32_t fEvents, uint32_t *pfEvents, RTMSINTERVAL cMillies);

/**
 * Shuts down one or both directions of communciation.
 *
 * @returns IPRT status code.
 * @param   hSocket         The socket handle.
 * @param   fRead           Whether to shutdown our read direction.
 * @param   fWrite          Whether to shutdown our write direction.
 */
RTDECL(int) RTSocketShutdown(RTSOCKET hSocket, bool fRead, bool fWrite);

/**
 * Gets the address of the local side.
 *
 * @returns IPRT status code.
 * @param   hSocket         The Socket handle.
 * @param   pAddr           Where to store the local address on success.
 */
RTDECL(int) RTSocketGetLocalAddress(RTSOCKET hSocket, PRTNETADDR pAddr);

/**
 * Gets the address of the other party.
 *
 * @returns IPRT status code.
 * @param   hSocket         The Socket handle.
 * @param   pAddr           Where to store the peer address on success.
 */
RTDECL(int) RTSocketGetPeerAddress(RTSOCKET hSocket, PRTNETADDR pAddr);

/**
 * Send data from a scatter/gather buffer to a socket.
 *
 * @returns IPRT status code.
 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
 *
 * @param   hSocket         The socket handle.
 * @param   pSgBuf          Scatter/gather buffer to write data to socket.
 */
RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf);

/**
 * Send data from multiple buffers to a socket.
 *
 * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
 * for lazy coders.  The "L" in the function name is short for "list" just like
 * in the execl libc API.
 *
 * @returns IPRT status code.
 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
 *
 * @param   hSocket         The socket handle.
 * @param   cSegs           The number of data segments in the following
 *                          ellipsis.
 * @param   ...             Pairs of buffer pointers (void const *) and buffer
 *                          sizes (size_t).  Make 101% sure the pointer is
 *                          really size_t.
 */
RTDECL(int) RTSocketSgWriteL(RTSOCKET hSocket, size_t cSegs, ...);

/**
 * Send data from multiple buffers to a socket.
 *
 * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
 * for lazy coders.  The "L" in the function name is short for "list" just like
 * in the execl libc API.
 *
 * @returns IPRT status code.
 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
 *
 * @param   hSocket         The socket handle.
 * @param   cSegs           The number of data segments in the following
 *                          argument list.
 * @param   va              Pairs of buffer pointers (void const *) and buffer
 *                          sizes (size_t).  Make 101% sure the pointer is
 *                          really size_t.
 */
RTDECL(int) RTSocketSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va);

/**
 * Receive data from a socket.
 *
 * This version doesn't block if there is no data on the socket.
 *
 * @returns IPRT status code.
 *
 * @param   hSocket         The socket handle.
 * @param   pvBuffer        Where to put the data we read.
 * @param   cbBuffer        Read buffer size.
 * @param   pcbRead         Number of bytes read.
 */
RTDECL(int) RTSocketReadNB(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead);

/**
 * Send data to a socket.
 *
 * This version doesn't block if there is not enough room for the message.
 *
 * @returns IPRT status code.
 *
 * @param   hSocket         The socket handle.
 * @param   pvBuffer        Buffer to write data to socket.
 * @param   cbBuffer        How much to write.
 * @param   pcbWritten      Number of bytes written.
 */
RTDECL(int) RTSocketWriteNB(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten);

/**
 * Send data to a socket, including destination address. Mainly useful
 * for datagram sockets.
 *
 * This version doesn't block if there is not enough room for the message.
 *
 * @returns IPRT status code.
 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
 *
 * @param   hSocket         The socket handle.
 * @param   pvBuffer        Buffer to write data to socket.
 * @param   cbBuffer        How much to write.
 * @param   pDstAddr        Pointer to destination address. May be NULL.
 */
RTDECL(int) RTSocketWriteToNB(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, PCRTNETADDR pDstAddr);

/**
 * Send data from a scatter/gather buffer to a socket.
 *
 * This version doesn't block if there is not enough room for the message.
 *
 * @returns iprt status code.
 *
 * @param   hSocket     The Socket handle.
 * @param   pSgBuf      Scatter/gather buffer to write data to socket.
 * @param   pcbWritten  Number of bytes written.
 */
RTR3DECL(int)  RTSocketSgWriteNB(RTSOCKET hSocket, PCRTSGBUF pSgBuf, size_t *pcbWritten);


/**
 * Send data from multiple buffers to a socket.
 *
 * This version doesn't block if there is not enough room for the message.
 * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
 * for lazy coders.  The "L" in the function name is short for "list" just like
 * in the execl libc API.
 *
 * @returns IPRT status code.
 *
 * @param   hSocket         The socket handle.
 * @param   cSegs           The number of data segments in the following
 *                          ellipsis.
 * @param   pcbWritten      Number of bytes written.
 * @param   ...             Pairs of buffer pointers (void const *) and buffer
 *                          sizes (size_t).  Make 101% sure the pointer is
 *                          really size_t.
 */
RTR3DECL(int) RTSocketSgWriteLNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, ...);

/**
 * Send data from multiple buffers to a socket.
 *
 * This version doesn't block if there is not enough room for the message.
 * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
 * for lazy coders.  The "L" in the function name is short for "list" just like
 * in the execl libc API.
 *
 * @returns IPRT status code.
 *
 * @param   hSocket         The socket handle.
 * @param   cSegs           The number of data segments in the following
 *                          argument list.
 * @param   pcbWritten      Number of bytes written.
 * @param   va              Pairs of buffer pointers (void const *) and buffer
 *                          sizes (size_t). Make 101% sure the pointer is
 *                          really size_t.
 */
RTR3DECL(int) RTSocketSgWriteLVNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, va_list va);

/** @} */
RT_C_DECLS_END

#endif /* !IPRT_INCLUDED_socket_h */