forked from youtube/cobalt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsocket.h
419 lines (368 loc) · 17.8 KB
/
socket.h
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
// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Module Overview: Starboard Socket module
//
// Defines Starboard socket I/O functions. Starboard supports IPv4 and IPv6,
// TCP and UDP, server and client sockets. Some platforms may not support IPv6,
// some may not support listening sockets, and some may not support any kind
// of sockets at all (or only allow them in debug builds).
//
// Starboard ONLY supports non-blocking socket I/O, so all sockets are
// non-blocking at creation time.
//
// Note that, on some platforms, API calls on one end of a socket connection
// may not be instantaneously aware of manipulations on the socket at the other
// end of the connection, thus requiring use of either an SbSocketWaiter or
// spin-polling.
//
// TODO: For platforms that do not support sockets at all, they must
// support at least a high-level HTTP client API (to be defined later).
#ifndef STARBOARD_SOCKET_H_
#define STARBOARD_SOCKET_H_
#include "starboard/export.h"
#include "starboard/time.h"
#include "starboard/types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Private structure representing a socket, which may or may not be connected or
// listening.
typedef struct SbSocketPrivate SbSocketPrivate;
// A handle to a socket.
typedef SbSocketPrivate* SbSocket;
// Enumeration of all Starboard socket operation results. Despite the enum
// name, note that the value actually describes the outcome of an operation,
// which is not always an error.
typedef enum SbSocketError {
// The operation succeeded.
kSbSocketOk = 0,
// The operation is blocked on I/O. Either try again "later," or be very
// clever and wait on it with a SbSocketWaiter.
kSbSocketPending,
// This socket error is generated when the connection is reset unexpectedly
// and the connection is now invalid.
// This might happen for example if an read packet has the "TCP RST" bit set.
kSbSocketErrorConnectionReset,
// The operation failed for some other reason not specified above.
kSbSocketErrorFailed,
} SbSocketError;
// All possible IP socket types.
typedef enum SbSocketProtocol {
// The TCP/IP protocol, a reliable, stateful, streaming protocol.
kSbSocketProtocolTcp,
// The UDP/IP protocol, an unreliable, connectionless, discrete packet
// (datagram) protocol.
kSbSocketProtocolUdp,
} SbSocketProtocol;
// All possible address types.
typedef enum SbSocketAddressType {
// An IPv4 address, using only the first 4 entries of the address buffer.
kSbSocketAddressTypeIpv4,
// An IPv6 address, which uses 16 entries of the address buffer.
kSbSocketAddressTypeIpv6,
} SbSocketAddressType;
// Bits that can be set when calling SbSocketResolve to filter the results.
typedef enum SbSocketResolveFilter {
// No filters, include everything.
kSbSocketResolveFilterNone = 0,
// Include Ipv4 addresses.
kSbSocketResolveFilterIpv4 = 1 << 0,
// Include Ipv6 addresses.
kSbSocketResolveFilterIpv6 = 1 << 1,
} SbSocketResolveFilter;
// A representation of any possible supported address type.
typedef struct SbSocketAddress {
// The storage for the address. For IPv4, only the first 4 bytes make up the
// address. For IPv6, the entire buffer of 16 bytes is meaningful. An address
// of all zeros means that the address is unspecified.
uint8_t address[16];
// The type of address this represents (IPv4 vs IPv6).
SbSocketAddressType type;
// The port component of this socket address. If not specified, it will be
// zero, which is officially undefined.
int port;
} SbSocketAddress;
// The result of a host name resolution.
typedef struct SbSocketResolution {
// An array of addresses associated with the host name.
SbSocketAddress* addresses;
// The length of the |addresses| array.
int address_count;
} SbSocketResolution;
// Well-defined value for an invalid socket handle.
#define kSbSocketInvalid ((SbSocket)NULL)
// Returns whether the given socket handle is valid.
static SB_C_INLINE bool SbSocketIsValid(SbSocket socket) {
return socket != kSbSocketInvalid;
}
// Returns whether IPV6 is supported on the current platform.
SB_EXPORT bool SbSocketIsIpv6Supported();
// Creates a new non-blocking socket for protocol |protocol| using address
// family |address_type|.
//
// - If successful, this function returns the newly created handle.
// - If unsuccessful, this function returns |kSbSocketInvalid| and also sets
// the last system error appropriately.
//
// |address_type|: The type of IP address to use for the socket.
// |protocol|: The protocol to use for the socket.
SB_EXPORT SbSocket SbSocketCreate(SbSocketAddressType address_type,
SbSocketProtocol protocol);
// Destroys the |socket| by flushing it, closing any connection that may be
// active on it, and reclaiming any resources associated with it, including
// any registration with an |SbSocketWaiter|.
//
// The return value indicates whether the destruction was successful. However,
// even if this function returns |false|, you should not be able to use the
// socket any more.
//
// |socket|: The SbSocket to be destroyed.
SB_EXPORT bool SbSocketDestroy(SbSocket socket);
// Opens a connection of |socket|'s type to the host and port specified by
// |address|. This function sets and returns the socket error if it is unable
// to connect to |address|. (It returns |kSbSocketOk| if it creates the
// connection successfully.)
//
// |socket|: The type of connection that should be opened.
// |address|: The host and port to which the socket should connect.
SB_EXPORT SbSocketError SbSocketConnect(SbSocket socket,
const SbSocketAddress* address);
// Binds |socket| to a specific local interface and port specified by
// |local_address|. This function sets and returns the socket error if it
// is unable to bind to |local_address|.
//
// |socket|: The SbSocket to be bound to the local interface.
// |local_address|: The local address to which the socket is to be bound.
// This value must not be |NULL|.
// - Setting the local address to port |0| (or not specifying a port) indicates
// that the function should choose a port for you.
// - Setting the IP address to |0.0.0.0| means that the socket should be bound
// to all interfaces.
SB_EXPORT SbSocketError SbSocketBind(SbSocket socket,
const SbSocketAddress* local_address);
// Causes |socket| to listen on the local address that |socket| was previously
// bound to by SbSocketBind. This function sets and returns the socket error if
// it is unable to listen for some reason. (It returns |kSbSocketOk| if it
// creates the connection successfully.)
//
// |socket|: The SbSocket on which the function operates.
SB_EXPORT SbSocketError SbSocketListen(SbSocket socket);
// Accepts a pending connection on |socket| and returns a new SbSocket
// representing that connection. This function sets the error on |socket|
// and returns |kSbSocketInvalid| if it is unable to accept a new connection.
//
// |socket|: The SbSocket that is accepting a pending connection.
SB_EXPORT SbSocket SbSocketAccept(SbSocket socket);
// Indicates whether |socket| is connected to anything. Invalid sockets are not
// connected.
//
// |socket|: The SbSocket to be checked.
SB_EXPORT bool SbSocketIsConnected(SbSocket socket);
// Returns whether |socket| is connected to anything, and, if so, whether it is
// receiving any data.
//
// |socket|: The SbSocket to be checked.
SB_EXPORT bool SbSocketIsConnectedAndIdle(SbSocket socket);
// Returns the last error set on |socket|. If |socket| is not valid, this
// function returns |kSbSocketErrorFailed|.
//
// |socket|: The SbSocket that the last error is returned for.
SB_EXPORT SbSocketError SbSocketGetLastError(SbSocket socket);
// Clears the last error set on |socket|. The return value indicates whether
// the socket error was cleared.
SB_EXPORT bool SbSocketClearLastError(SbSocket socket);
// Gets the address that this socket is bound to locally, if the socket is
// connected. The return value indicates whether the address was retrieved
// successfully.
//
// |socket|: The SbSocket for which the local address is retrieved.
// |out_address|: The SbSocket's local address.
SB_EXPORT bool SbSocketGetLocalAddress(SbSocket socket,
SbSocketAddress* out_address);
// Gets the source address and the netmask that would be used to connect to the
// destination. The netmask parameter is optional, and only populated if a
// non-NULL parameter is passed in. To determine which source IP will be used,
// the kernel takes into account the protocol, routes, destination
// ip, etc. The subnet mask, aka netmask, is used to find the routing prefix.
// In IPv6, this should be derived from the prefix value.
//
// Returns whether it was possible to determine the source address and the
// netmask (if non-NULL value is passed) to be used to connect to the
// destination. This function could fail if the destination is not reachable,
// if it an invalid address, etc.
//
// |destination|: The destination IP to be connected to. If IP addresses is not
// 0.0.0.0 or ::, then temporary addresses may be returned.
//
// If the destination address is 0.0.0.0, and its |type| is
// |kSbSocketAddressTypeIpv4|, then any IPv4 local interface that is up and not
// a loopback interface is a valid return value.
//
// If the destination address is ::, and its |type| is
// |kSbSocketAddressTypeIpv6| then any IPv6 local interface that is up and not
// loopback or a link-local IP is a valid return value. However, in the case of
// IPv6, the address with the biggest scope must be returned. E.g., a globally
// scoped and routable IP is preferred over a unique local address (ULA). Also,
// the IP address that is returned must be permanent.
//
// If destination address is NULL, then any IP address that is valid for
// |destination| set to 0.0.0.0 (IPv4) or :: (IPv6) can be returned.
//
// |out_source_address|: This function places the address of the local interface
// in this output variable.
// |out_netmask|: This parameter is optional. If a non-NULL value is passed in,
// this function places the netmask associated with the source address in this
// output variable.
SB_EXPORT bool SbSocketGetInterfaceAddress(
const SbSocketAddress* const destination,
SbSocketAddress* out_source_address,
SbSocketAddress* out_netmask);
// Reads up to |data_size| bytes from |socket| into |out_data| and places the
// source address of the packet in |out_source| if out_source is not NULL.
// Returns the number of bytes read, or a negative number if there is an error,
// in which case SbSocketGetLastError can provide the precise error encountered.
//
// Note that this function is NOT specified to make a best effort to read all
// data on all platforms, but it MAY still do so. It is specified to read
// however many bytes are available conveniently, meaning that it should avoid
// blocking until there is data. It can be run in a loop until
// SbSocketGetLastError returns |kSbSocketPending| to make it a best-effort
// read (but still only up to not blocking, unless you want to spin).
//
// The primary use of |out_source| is to receive datagram packets from
// multiple sources on a UDP server socket. TCP has two endpoints connected
// persistently, so the address is unnecessary, but allowed.
//
// |socket|: The SbSocket from which data is read.
// |out_data|: The data read from the socket. Must not be NULL.
// |data_size|: The number of bytes to read.
// |out_source|: The source address of the packet.
SB_EXPORT int SbSocketReceiveFrom(SbSocket socket,
char* out_data,
int data_size,
SbSocketAddress* out_source);
// Writes up to |data_size| bytes of |data| to |destination| via
// |socket|. Returns the number of bytes written, or a negative number if
// there is an error, in which case |SbSocketGetLastError| can provide the
// precise error encountered.
//
// Note that this function is NOT specified to make a best effort to write all
// data on all platforms, but it MAY still do so. It is specified to write
// however many bytes are available conveniently. It can be run in a loop
// until SbSocketGetLastError returns |kSbSocketPending| to make it a
// best-effort write (but still only up to not blocking, unless you want to
// spin).
//
// |socket|: The SbSocket to use to write data.
// |data|: The data written to the socket. Must not be NULL.
// |data_size|: The number of bytes of |data| to write.
// |destination|: The location to which data is written. This value must be
// |NULL| for TCP connections, which can only have a single endpoint.
//
// The primary use of |destination| is to send datagram packets, which can
// go out to multiple sources from a single UDP server socket. TCP has two
// endpoints connected persistently, so setting |destination| when sending
// to a TCP socket will cause an error.
SB_EXPORT int SbSocketSendTo(SbSocket socket,
const char* data,
int data_size,
const SbSocketAddress* destination);
// Sets the |SO_BROADCAST|, or equivalent, option to |value| on |socket|. The
// return value indicates whether the option was actually set.
//
// This option is only meaningful for UDP sockets and allows the socket to
// send to the broadcast address.
//
// |socket|: The SbSocket for which the option is set.
// |value|: The new value for the option.
SB_EXPORT bool SbSocketSetBroadcast(SbSocket socket, bool value);
// Sets the |SO_REUSEADDR|, or equivalent, option to |value| on |socket|.
// The return value indicates whether the option was actually set.
//
// This option allows a bound address to be reused if a socket isn't actively
// bound to it.
//
// |socket|: The SbSocket for which the option is set.
// |value|: The new value for the option.
SB_EXPORT bool SbSocketSetReuseAddress(SbSocket socket, bool value);
// Sets the |SO_RCVBUF|, or equivalent, option to |size| on |socket|. The
// return value indicates whether the option was actually set.
//
// |socket|: The SbSocket for which the option is set.
// |size|: The value for the option.
SB_EXPORT bool SbSocketSetReceiveBufferSize(SbSocket socket, int32_t size);
// Sets the |SO_SNDBUF|, or equivalent, option to |size| on |socket|. The
// return value indicates whether the option was actually set.
//
// |socket|: The SbSocket for which the option is set.
// |size|: The value for the option.
SB_EXPORT bool SbSocketSetSendBufferSize(SbSocket socket, int32_t size);
// Sets the |SO_KEEPALIVE|, or equivalent, option to |value| on |socket|. The
// return value indicates whether the option was actually set.
//
// |socket|: The SbSocket for which the option is set.
// |value|: If set to |true|, then |period| specifies the minimum time
// (SbTime) is always in microseconds) between keep-alive packets. If
// set to |false|, |period| is ignored.
// |period|: The time between keep-alive packets. This value is only relevant
// if |value| is |true|.
SB_EXPORT bool SbSocketSetTcpKeepAlive(SbSocket socket,
bool value,
SbTime period);
// Sets the |TCP_NODELAY|, or equivalent, option to |value| on |socket|. The
// return value indicates whether the option was actually set.
//
// This function disables the Nagle algorithm for reducing the number of
// packets sent when converting from a stream to packets. Disabling Nagle
// generally puts the data for each Send call into its own packet, but does
// not guarantee that behavior.
//
// |socket|: The SbSocket for which the option is set.
// |value|: Indicates whether the Nagle algorithm should be disabled
// (|value|=|true|).
SB_EXPORT bool SbSocketSetTcpNoDelay(SbSocket socket, bool value);
// Sets the |SO_WINSCALE|, or equivalent, option to |value| on |socket|. The
// return value indicates whether the option was actually set.
//
// |socket|: The SbSocket for which the option is set.
// |value|: The value for the option.
SB_EXPORT bool SbSocketSetTcpWindowScaling(SbSocket socket, bool value);
// Joins |socket| to an IP multicast group identified by |address|. The
// equivalent of IP_ADD_MEMBERSHIP. The return value indicates whether the
// socket was joined to the group successfully.
//
// |socket|: The SbSocket to be joined to the IP multicast group.
// |address|: The location of the IP multicast group.
SB_EXPORT bool SbSocketJoinMulticastGroup(SbSocket socket,
const SbSocketAddress* address);
// Synchronously resolves |hostname| into the returned SbSocketResolution,
// which must be freed with SbSocketFreeResolution. The function returns
// |NULL| if it is unable to resolve |hostname|.
//
// |hostname|: The hostname to be resolved.
// |filters|: A mask of SbSocketResolveFilter values used to filter the
// resolution. If |filters| does not specify an IP address family filter,
// all address families are included. However, if one IP address family filter
// is specified, only that address family is included. The function ignores
// unrecognized filter bits.
SB_EXPORT SbSocketResolution* SbSocketResolve(const char* hostname,
int filters);
// Frees a resolution allocated by SbSocketResolve.
//
// |resolution|: The resolution to be freed.
SB_EXPORT void SbSocketFreeResolution(SbSocketResolution* resolution);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // STARBOARD_SOCKET_H_