iodine 0.4.19 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +1 -2
- data/CHANGELOG.md +22 -0
- data/LIMITS.md +19 -9
- data/README.md +92 -77
- data/SPEC-PubSub-Draft.md +113 -0
- data/SPEC-Websocket-Draft.md +127 -143
- data/bin/http-hello +0 -1
- data/bin/raw-rbhttp +1 -1
- data/bin/raw_broadcast +8 -10
- data/bin/updated api +2 -2
- data/bin/ws-broadcast +2 -4
- data/bin/ws-echo +2 -2
- data/examples/config.ru +13 -13
- data/examples/echo.ru +5 -6
- data/examples/hello.ru +2 -3
- data/examples/info.md +316 -0
- data/examples/pubsub_engine.ru +81 -0
- data/examples/redis.ru +9 -9
- data/examples/shootout.ru +45 -11
- data/ext/iodine/defer.c +194 -297
- data/ext/iodine/defer.h +61 -53
- data/ext/iodine/evio.c +0 -260
- data/ext/iodine/evio.h +50 -22
- data/ext/iodine/evio_callbacks.c +26 -0
- data/ext/iodine/evio_epoll.c +251 -0
- data/ext/iodine/evio_kqueue.c +193 -0
- data/ext/iodine/extconf.rb +1 -1
- data/ext/iodine/facil.c +1420 -542
- data/ext/iodine/facil.h +151 -64
- data/ext/iodine/fio_ary.h +418 -0
- data/ext/iodine/{base64.c → fio_base64.c} +33 -24
- data/ext/iodine/{base64.h → fio_base64.h} +6 -7
- data/ext/iodine/{fio_cli_helper.c → fio_cli.c} +77 -58
- data/ext/iodine/{fio_cli_helper.h → fio_cli.h} +9 -4
- data/ext/iodine/fio_hashmap.h +759 -0
- data/ext/iodine/fio_json_parser.h +651 -0
- data/ext/iodine/fio_llist.h +257 -0
- data/ext/iodine/fio_mem.c +672 -0
- data/ext/iodine/fio_mem.h +140 -0
- data/ext/iodine/fio_random.c +248 -0
- data/ext/iodine/{random.h → fio_random.h} +11 -14
- data/ext/iodine/{sha1.c → fio_sha1.c} +28 -24
- data/ext/iodine/{sha1.h → fio_sha1.h} +38 -16
- data/ext/iodine/{sha2.c → fio_sha2.c} +66 -49
- data/ext/iodine/{sha2.h → fio_sha2.h} +57 -26
- data/ext/iodine/{fiobj_internal.c → fio_siphash.c} +9 -90
- data/ext/iodine/fio_siphash.h +18 -0
- data/ext/iodine/fio_tmpfile.h +38 -0
- data/ext/iodine/fiobj.h +24 -7
- data/ext/iodine/fiobj4sock.h +23 -0
- data/ext/iodine/fiobj_ary.c +143 -226
- data/ext/iodine/fiobj_ary.h +17 -16
- data/ext/iodine/fiobj_data.c +1160 -0
- data/ext/iodine/fiobj_data.h +164 -0
- data/ext/iodine/fiobj_hash.c +298 -406
- data/ext/iodine/fiobj_hash.h +101 -54
- data/ext/iodine/fiobj_json.c +478 -601
- data/ext/iodine/fiobj_json.h +34 -9
- data/ext/iodine/fiobj_numbers.c +383 -51
- data/ext/iodine/fiobj_numbers.h +87 -11
- data/ext/iodine/fiobj_str.c +423 -184
- data/ext/iodine/fiobj_str.h +81 -32
- data/ext/iodine/fiobject.c +273 -522
- data/ext/iodine/fiobject.h +477 -112
- data/ext/iodine/http.c +2243 -83
- data/ext/iodine/http.h +842 -121
- data/ext/iodine/http1.c +810 -385
- data/ext/iodine/http1.h +16 -39
- data/ext/iodine/http1_parser.c +146 -74
- data/ext/iodine/http1_parser.h +15 -4
- data/ext/iodine/http_internal.c +1258 -0
- data/ext/iodine/http_internal.h +226 -0
- data/ext/iodine/http_mime_parser.h +341 -0
- data/ext/iodine/iodine.c +86 -68
- data/ext/iodine/iodine.h +26 -11
- data/ext/iodine/iodine_helpers.c +8 -7
- data/ext/iodine/iodine_http.c +487 -324
- data/ext/iodine/iodine_json.c +304 -0
- data/ext/iodine/iodine_json.h +6 -0
- data/ext/iodine/iodine_protocol.c +107 -45
- data/ext/iodine/iodine_pubsub.c +526 -225
- data/ext/iodine/iodine_pubsub.h +10 -0
- data/ext/iodine/iodine_websockets.c +268 -510
- data/ext/iodine/iodine_websockets.h +2 -4
- data/ext/iodine/pubsub.c +726 -432
- data/ext/iodine/pubsub.h +85 -103
- data/ext/iodine/rb-call.c +4 -4
- data/ext/iodine/rb-defer.c +46 -22
- data/ext/iodine/rb-fiobj2rb.h +117 -0
- data/ext/iodine/rb-rack-io.c +73 -238
- data/ext/iodine/rb-rack-io.h +2 -2
- data/ext/iodine/rb-registry.c +35 -93
- data/ext/iodine/rb-registry.h +1 -0
- data/ext/iodine/redis_engine.c +742 -304
- data/ext/iodine/redis_engine.h +42 -39
- data/ext/iodine/resp_parser.h +311 -0
- data/ext/iodine/sock.c +627 -490
- data/ext/iodine/sock.h +345 -297
- data/ext/iodine/spnlock.inc +15 -4
- data/ext/iodine/websocket_parser.h +16 -20
- data/ext/iodine/websockets.c +188 -257
- data/ext/iodine/websockets.h +24 -133
- data/lib/iodine.rb +52 -7
- data/lib/iodine/cli.rb +6 -24
- data/lib/iodine/json.rb +40 -0
- data/lib/iodine/version.rb +1 -1
- data/lib/iodine/websocket.rb +5 -3
- data/lib/rack/handler/iodine.rb +58 -13
- metadata +38 -48
- data/bin/ws-shootout +0 -107
- data/examples/broadcast.ru +0 -56
- data/ext/iodine/bscrypt-common.h +0 -116
- data/ext/iodine/bscrypt.h +0 -49
- data/ext/iodine/fio2resp.c +0 -60
- data/ext/iodine/fio2resp.h +0 -51
- data/ext/iodine/fio_dict.c +0 -446
- data/ext/iodine/fio_dict.h +0 -99
- data/ext/iodine/fio_hash_table.h +0 -370
- data/ext/iodine/fio_list.h +0 -111
- data/ext/iodine/fiobj_internal.h +0 -280
- data/ext/iodine/fiobj_primitives.c +0 -131
- data/ext/iodine/fiobj_primitives.h +0 -55
- data/ext/iodine/fiobj_sym.c +0 -135
- data/ext/iodine/fiobj_sym.h +0 -60
- data/ext/iodine/hex.c +0 -124
- data/ext/iodine/hex.h +0 -70
- data/ext/iodine/http1_request.c +0 -81
- data/ext/iodine/http1_request.h +0 -58
- data/ext/iodine/http1_response.c +0 -417
- data/ext/iodine/http1_response.h +0 -95
- data/ext/iodine/http_request.c +0 -111
- data/ext/iodine/http_request.h +0 -102
- data/ext/iodine/http_response.c +0 -1703
- data/ext/iodine/http_response.h +0 -250
- data/ext/iodine/misc.c +0 -182
- data/ext/iodine/misc.h +0 -74
- data/ext/iodine/random.c +0 -208
- data/ext/iodine/redis_connection.c +0 -278
- data/ext/iodine/redis_connection.h +0 -86
- data/ext/iodine/resp.c +0 -842
- data/ext/iodine/resp.h +0 -261
- data/ext/iodine/siphash.c +0 -154
- data/ext/iodine/siphash.h +0 -22
- data/ext/iodine/xor-crypt.c +0 -193
- data/ext/iodine/xor-crypt.h +0 -107
data/ext/iodine/sock.h
CHANGED
@@ -7,58 +7,63 @@ License: MIT
|
|
7
7
|
Feel free to copy, use and enjoy according to the license provided.
|
8
8
|
*/
|
9
9
|
#define LIB_SOCK_VERSION_MAJOR 0
|
10
|
-
#define LIB_SOCK_VERSION_MINOR
|
11
|
-
#define LIB_SOCK_VERSION_PATCH
|
10
|
+
#define LIB_SOCK_VERSION_MINOR 4
|
11
|
+
#define LIB_SOCK_VERSION_PATCH 0
|
12
12
|
|
13
|
+
#ifndef LIB_SOCK_MAX_CAPACITY
|
14
|
+
/** The maximum `fd` value `sock.h` should support. */
|
15
|
+
#define LIB_SOCK_MAX_CAPACITY 131072
|
16
|
+
#endif
|
13
17
|
/** \file
|
14
|
-
The `sock.h` is a non-blocking socket helper library, using a user level
|
15
|
-
non-blocking sockets and some helper functions.
|
16
|
-
|
17
|
-
This library is great when using it alongside `evio.h`.
|
18
|
-
|
19
|
-
The library is designed to be thread safe, but not fork safe - mostly since
|
20
|
-
sockets, except listenning sockets, shouldn't be shared among processes.
|
21
|
-
|
22
|
-
Socket connections accepted or created using this library will use the
|
23
|
-
TCP_NODELAY option by default.
|
24
|
-
|
25
|
-
Non TCP/IP stream sockets and file descriptors (i.e., unix sockets) can be
|
26
|
-
safely used with this library. However, file descriptors that can't use the
|
27
|
-
`read` or `write` system calls MUST set correct Read / Write hooks or they
|
28
|
-
fail.
|
29
|
-
*/
|
18
|
+
* The `sock.h` is a non-blocking socket helper library, using a user level
|
19
|
+
* buffer, non-blocking sockets and some helper functions.
|
20
|
+
*
|
21
|
+
* This library is great when using it alongside `evio.h`.
|
22
|
+
*
|
23
|
+
* The library is designed to be thread safe, but not fork safe - mostly since
|
24
|
+
* sockets, except listenning sockets, shouldn't be shared among processes.
|
25
|
+
*
|
26
|
+
* Socket connections accepted or created using this library will use the
|
27
|
+
* TCP_NODELAY option by default.
|
28
|
+
*
|
29
|
+
* Non TCP/IP stream sockets and file descriptors (i.e., unix sockets) can be
|
30
|
+
* safely used with this library. However, file descriptors that can't use the
|
31
|
+
* `read` or `write` system calls MUST set correct Read / Write hooks or they
|
32
|
+
* will fail.
|
33
|
+
*/
|
30
34
|
|
31
35
|
#include <stdint.h>
|
32
36
|
#include <stdio.h>
|
33
37
|
#include <stdlib.h>
|
38
|
+
#include <string.h>
|
34
39
|
#include <sys/types.h>
|
35
40
|
#include <unistd.h>
|
36
41
|
|
37
|
-
|
38
|
-
#
|
42
|
+
// clang-format off
|
43
|
+
#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
|
44
|
+
# if defined(__has_include)
|
45
|
+
# if __has_include(<endian.h>)
|
46
|
+
# include <endian.h>
|
47
|
+
# elif __has_include(<sys/endian.h>)
|
48
|
+
# include <sys/endian.h>
|
49
|
+
# endif
|
50
|
+
# endif
|
51
|
+
# if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) && \
|
52
|
+
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
53
|
+
# define __BIG_ENDIAN__
|
54
|
+
# endif
|
39
55
|
#endif
|
56
|
+
// clang-format on
|
40
57
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
This information is also useful when implementing read / write hooks.
|
45
|
-
*/
|
46
|
-
#ifndef BUFFER_PACKET_SIZE
|
47
|
-
#define BUFFER_PACKET_SIZE \
|
48
|
-
(1024 * 16) /* Use 32 Kb. With sendfile, 16 Kb appears to work better. */
|
49
|
-
#endif
|
50
|
-
#ifndef BUFFER_FILE_READ_SIZE
|
51
|
-
#define BUFFER_FILE_READ_SIZE 4096UL
|
52
|
-
#endif
|
53
|
-
#ifndef BUFFER_PACKET_POOL
|
54
|
-
#define BUFFER_PACKET_POOL 1024
|
58
|
+
#ifndef UNUSED_FUNC
|
59
|
+
#define UNUSED_FUNC __attribute__((unused))
|
55
60
|
#endif
|
56
61
|
|
57
62
|
/* *****************************************************************************
|
58
63
|
A simple, predictable UUID for file-descriptors, for collision prevention
|
59
64
|
*/
|
60
65
|
#ifndef sock_uuid2fd
|
61
|
-
#define sock_uuid2fd(uuid) ((
|
66
|
+
#define sock_uuid2fd(uuid) ((int)((uintptr_t)uuid >> 8))
|
62
67
|
#endif
|
63
68
|
|
64
69
|
/* *****************************************************************************
|
@@ -69,15 +74,18 @@ extern "C" {
|
|
69
74
|
#endif
|
70
75
|
|
71
76
|
/* *****************************************************************************
|
72
|
-
Process wide and helper
|
77
|
+
Process wide and helper sock API.
|
73
78
|
*/
|
74
79
|
|
75
|
-
/**
|
76
|
-
|
80
|
+
/** MUST be called after forking a process. */
|
81
|
+
void sock_on_fork(void);
|
77
82
|
|
78
|
-
|
79
|
-
|
80
|
-
|
83
|
+
/**
|
84
|
+
* Sets a socket to non blocking state.
|
85
|
+
*
|
86
|
+
* This function is called automatically for the new socket, when using
|
87
|
+
* `sock_accept` or `sock_connect`.
|
88
|
+
*/
|
81
89
|
int sock_set_non_block(int fd);
|
82
90
|
|
83
91
|
/**
|
@@ -90,103 +98,119 @@ extended to the allowed "hard" limit.
|
|
90
98
|
ssize_t sock_max_capacity(void);
|
91
99
|
|
92
100
|
/* *****************************************************************************
|
93
|
-
The main
|
101
|
+
The main sock API.
|
94
102
|
*/
|
95
103
|
|
96
104
|
/**
|
97
|
-
Opens a listening non-blocking socket. Return's the socket's UUID.
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
the
|
109
|
-
|
105
|
+
* Opens a listening non-blocking socket. Return's the socket's UUID.
|
106
|
+
*
|
107
|
+
* If `port` is provided (`address` can be NULL), a TCP/IP socket will be
|
108
|
+
* opened. Otherwise, `address` is required and a Unix Socket will be used
|
109
|
+
* (remember Unix Sockets have name length restrictions).
|
110
|
+
*
|
111
|
+
* Returns -1 on error. Returns a valid socket (non-random) UUID.
|
112
|
+
*
|
113
|
+
* UUIDs with values less then -1 are valid values, depending on the system's
|
114
|
+
* byte-ordering.
|
115
|
+
*
|
116
|
+
* Socket UUIDs are predictable and shouldn't be used outside the local system.
|
117
|
+
* They protect against connection mixups on concurrent systems (i.e. when
|
118
|
+
* saving client data for "broadcasting" or when an old client task is preparing
|
119
|
+
* a response in the background while a disconnection and a new connection occur
|
120
|
+
* on the same `fd`).
|
121
|
+
*/
|
110
122
|
intptr_t sock_listen(const char *address, const char *port);
|
111
123
|
|
112
124
|
/**
|
113
|
-
`sock_accept` accepts a new socket connection from the listening socket
|
114
|
-
`server_fd`, allowing the use of `sock_` functions with this new file
|
115
|
-
descriptor.
|
116
|
-
|
117
|
-
When using `
|
118
|
-
listen for events.
|
119
|
-
|
120
|
-
Returns -1 on error. Returns a valid socket (non-random) UUID.
|
121
|
-
|
122
|
-
Socket UUIDs are predictable and shouldn't be used outside the local system.
|
123
|
-
They protect against connection mixups on concurrent systems (i.e. when saving
|
124
|
-
client data for "broadcasting" or when an old client task is preparing a
|
125
|
-
response in the background while a disconnection and a new connection occur on
|
126
|
-
the same `fd`).
|
125
|
+
* `sock_accept` accepts a new socket connection from the listening socket
|
126
|
+
* `server_fd`, allowing the use of `sock_` functions with this new file
|
127
|
+
* descriptor.
|
128
|
+
|
129
|
+
* When using `evio`, remember to call `int evio_add(intptr_t uuid);` to
|
130
|
+
* listen for events.
|
131
|
+
*
|
132
|
+
* Returns -1 on error. Returns a valid socket (non-random) UUID.
|
133
|
+
*
|
134
|
+
* Socket UUIDs are predictable and shouldn't be used outside the local system.
|
135
|
+
* They protect against connection mixups on concurrent systems (i.e. when saving
|
136
|
+
* client data for "broadcasting" or when an old client task is preparing a
|
137
|
+
* response in the background while a disconnection and a new connection occur on
|
138
|
+
* the same `fd`).
|
127
139
|
*/
|
128
140
|
intptr_t sock_accept(intptr_t srv_uuid);
|
129
141
|
|
130
142
|
/**
|
131
|
-
`sock_connect` is similar to `sock_accept` but should be used to initiate a
|
132
|
-
client connection to the address requested.
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
the
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
143
|
+
* `sock_connect` is similar to `sock_accept` but should be used to initiate a
|
144
|
+
* client connection to the address requested.
|
145
|
+
*
|
146
|
+
* If `port` is provided (`address` can be NULL), a TCP/IP socket will be
|
147
|
+
* opened. Otherwise, `address` is required and a Unix Socket will be used
|
148
|
+
* (remember Unix Sockets have name length restrictions).
|
149
|
+
*
|
150
|
+
* Returns -1 on error. Returns a valid socket (non-random) UUID.
|
151
|
+
*
|
152
|
+
* Socket UUIDs are predictable and shouldn't be used outside the local system.
|
153
|
+
* They protect against connection mixups on concurrent systems (i.e. when
|
154
|
+
* saving client data for "broadcasting" or when an old client task is preparing
|
155
|
+
* a response in the background while a disconnection and a new connection occur
|
156
|
+
* on the same `fd`).
|
157
|
+
*
|
158
|
+
* When using `evio`, remember to call `int evio_add(sock_fd2uuid(uuid),
|
159
|
+
* (void*)uuid);` to listen for events.
|
160
|
+
*
|
161
|
+
* NOTICE:
|
162
|
+
*
|
163
|
+
* This function is non-blocking, meaning that the connection probably wasn't
|
164
|
+
* established by the time the function returns (this prevents the function from
|
165
|
+
* hanging while waiting for a network timeout).
|
166
|
+
*
|
167
|
+
* Use select, poll, `evio` or other solutions to review the connection state
|
168
|
+
* before attempting to write to the socket.
|
169
|
+
*/
|
154
170
|
intptr_t sock_connect(char *address, char *port);
|
155
171
|
|
156
172
|
/**
|
157
|
-
`sock_open` takes an existing file descriptor `fd` and initializes it's status
|
158
|
-
as open and available for `
|
159
|
-
|
160
|
-
This will reinitialize the data (user buffer etc') for the file descriptor
|
161
|
-
provided, calling the `sock_on_close` callback if the `fd` was previously
|
162
|
-
marked as used.
|
163
|
-
|
164
|
-
When using `evio`, remember to call `int evio_add(sock_fd2uuid(uuid),
|
165
|
-
(void*)uuid);` to listen for events.
|
166
|
-
|
167
|
-
Returns -1 on error. Returns a valid socket (non-random) UUID.
|
168
|
-
|
169
|
-
Socket UUIDs are predictable and shouldn't be used outside the local system.
|
170
|
-
They protect against connection mixups on concurrent systems (i.e. when saving
|
171
|
-
client data for "broadcasting" or when an old client task is preparing a
|
172
|
-
response in the background while a disconnection and a new connection occur on
|
173
|
-
the same `fd`).
|
173
|
+
* `sock_open` takes an existing file descriptor `fd` and initializes it's status
|
174
|
+
* as open and available for `sock_*` API calls, returning a valid UUID.
|
175
|
+
*
|
176
|
+
* This will reinitialize the data (user buffer etc') for the file descriptor
|
177
|
+
* provided, calling the `sock_on_close` callback if the `fd` was previously
|
178
|
+
* marked as used.
|
179
|
+
|
180
|
+
* When using `evio`, remember to call `int evio_add(sock_fd2uuid(uuid),
|
181
|
+
* (void*)uuid);` to listen for events.
|
182
|
+
*
|
183
|
+
* Returns -1 on error. Returns a valid socket (non-random) UUID.
|
184
|
+
*
|
185
|
+
* Socket UUIDs are predictable and shouldn't be used outside the local system.
|
186
|
+
* They protect against connection mixups on concurrent systems (i.e. when saving
|
187
|
+
* client data for "broadcasting" or when an old client task is preparing a
|
188
|
+
* response in the background while a disconnection and a new connection occur on
|
189
|
+
* the same `fd`).
|
174
190
|
*/
|
175
191
|
intptr_t sock_open(int fd);
|
176
192
|
|
177
193
|
/**
|
178
|
-
Returns 1 if the uuid refers to a valid and open, socket.
|
194
|
+
* Returns 1 if the uuid refers to a valid and open, socket.
|
195
|
+
*
|
196
|
+
* Returns 0 if not.
|
197
|
+
*/
|
198
|
+
int sock_isvalid(intptr_t uuid);
|
199
|
+
|
200
|
+
/**
|
201
|
+
Returns 1 if the uuid is invalid or the socket is flagged to be closed.
|
179
202
|
|
180
|
-
Returns 0 if
|
203
|
+
Returns 0 if the socket is valid, open and isn't flagged to be closed.
|
181
204
|
*/
|
182
|
-
int
|
205
|
+
int sock_isclosed(intptr_t uuid);
|
183
206
|
|
184
207
|
/** The return type for the `sock_peer_addr` function. */
|
185
208
|
typedef struct {
|
186
209
|
uint32_t addrlen;
|
187
210
|
struct sockaddr *addr;
|
188
211
|
} sock_peer_addr_s;
|
189
|
-
/**
|
212
|
+
/**
|
213
|
+
* Returns the information available about the socket's peer address.
|
190
214
|
*
|
191
215
|
* If no information is available, the struct will be initialized with zero
|
192
216
|
* (`addr == NULL`).
|
@@ -196,66 +220,67 @@ typedef struct {
|
|
196
220
|
sock_peer_addr_s sock_peer_addr(intptr_t uuid);
|
197
221
|
|
198
222
|
/**
|
199
|
-
`sock_fd2uuid` takes an existing file decriptor `fd` and returns it's active
|
200
|
-
`uuid`.
|
201
|
-
|
202
|
-
If the file descriptor is marked as closed (wasn't opened / registered with
|
203
|
-
`libsock`) the function returns -1;
|
204
|
-
|
205
|
-
If the file descriptor was closed remotely (or not using `libsock`), a false
|
206
|
-
positive will be possible. This is not an issue, since the use of an invalid
|
207
|
-
|
208
|
-
|
209
|
-
|
223
|
+
* `sock_fd2uuid` takes an existing file decriptor `fd` and returns it's active
|
224
|
+
* `uuid`.
|
225
|
+
|
226
|
+
* If the file descriptor is marked as closed (wasn't opened / registered with
|
227
|
+
* `libsock`) the function returns -1;
|
228
|
+
*
|
229
|
+
* If the file descriptor was closed remotely (or not using `libsock`), a false
|
230
|
+
* positive will be possible. This is not an issue, since the use of an invalid
|
231
|
+
fd
|
232
|
+
* will result in the registry being updated and the fd being closed.
|
233
|
+
*
|
234
|
+
* Returns -1 on error. Returns a valid socket (non-random) UUID.
|
210
235
|
*/
|
211
236
|
intptr_t sock_fd2uuid(int fd);
|
212
237
|
|
213
238
|
/**
|
214
|
-
OVERRIDABLE:
|
215
|
-
|
216
|
-
"Touches" a socket connection.
|
217
|
-
|
218
|
-
This is a place holder for an optional callback for systems that apply
|
219
|
-
reviews.
|
220
|
-
|
221
|
-
`sock` supplies a default implementation (that does nothing) is cases where a
|
222
|
-
callback wasn't defined.
|
223
|
-
*/
|
239
|
+
* OVERRIDABLE:
|
240
|
+
*
|
241
|
+
* "Touches" a socket connection.
|
242
|
+
*
|
243
|
+
* This is a place holder for an optional callback for systems that apply
|
244
|
+
* timeout reviews.
|
245
|
+
*
|
246
|
+
* `sock` supplies a default implementation (that does nothing) is cases where a
|
247
|
+
* callback wasn't defined.
|
248
|
+
*/
|
224
249
|
void sock_touch(intptr_t uuid);
|
225
250
|
|
226
251
|
/**
|
227
|
-
OVERRIDABLE:.
|
228
|
-
|
229
|
-
This is a place holder for an optional callback for when the socket is closed
|
230
|
-
locally.
|
231
|
-
|
232
|
-
Notice that calling `sock_close()` won't close the socket before all the data
|
233
|
-
the buffer is sent. This function will be called only one the connection
|
234
|
-
actually closed.
|
235
|
-
|
236
|
-
`sock` supplies a default implementation (that does nothing) is cases where a
|
237
|
-
callback wasn't defined.
|
238
|
-
*/
|
252
|
+
* OVERRIDABLE:.
|
253
|
+
*
|
254
|
+
* This is a place holder for an optional callback for when the socket is closed
|
255
|
+
* locally.
|
256
|
+
*
|
257
|
+
* Notice that calling `sock_close()` won't close the socket before all the data
|
258
|
+
* in the buffer is sent. This function will be called only one the connection
|
259
|
+
* is actually closed.
|
260
|
+
*
|
261
|
+
* `sock` supplies a default implementation (that does nothing) is cases where a
|
262
|
+
* callback wasn't defined.
|
263
|
+
*/
|
239
264
|
void sock_on_close(intptr_t uuid);
|
240
265
|
|
241
266
|
/**
|
242
|
-
`sock_read` attempts to read up to count bytes from the socket into the
|
243
|
-
starting at buf.
|
244
|
-
|
245
|
-
`sock_read`'s return values are wildly different then the native return
|
246
|
-
and they aim at making far simpler sense.
|
247
|
-
|
248
|
-
`sock_read` returns the number of bytes read (0 is a valid return value which
|
249
|
-
simply means that no bytes were read from the buffer).
|
250
|
-
|
251
|
-
On a connection error (NOT EAGAIN or EWOULDBLOCK), signal interrupt, or when
|
252
|
-
connection was closed, `sock_read` returns -1.
|
253
|
-
|
254
|
-
The value 0 is the valid value indicating no data was read.
|
255
|
-
|
256
|
-
Data might be available in the kernel's buffer while it is not available to
|
257
|
-
read using `sock_read` (i.e., when using a transport layer, such as TLS).
|
258
|
-
*/
|
267
|
+
* `sock_read` attempts to read up to count bytes from the socket into the
|
268
|
+
* buffer starting at buf.
|
269
|
+
*
|
270
|
+
* `sock_read`'s return values are wildly different then the native return
|
271
|
+
* values and they aim at making far simpler sense.
|
272
|
+
*
|
273
|
+
* `sock_read` returns the number of bytes read (0 is a valid return value which
|
274
|
+
* simply means that no bytes were read from the buffer).
|
275
|
+
*
|
276
|
+
* On a connection error (NOT EAGAIN or EWOULDBLOCK), signal interrupt, or when
|
277
|
+
* the connection was closed, `sock_read` returns -1.
|
278
|
+
*
|
279
|
+
* The value 0 is the valid value indicating no data was read.
|
280
|
+
*
|
281
|
+
* Data might be available in the kernel's buffer while it is not available to
|
282
|
+
* be read using `sock_read` (i.e., when using a transport layer, such as TLS).
|
283
|
+
*/
|
259
284
|
ssize_t sock_read(intptr_t uuid, void *buf, size_t count);
|
260
285
|
|
261
286
|
typedef struct {
|
@@ -268,27 +293,31 @@ typedef struct {
|
|
268
293
|
const intptr_t data_fd;
|
269
294
|
};
|
270
295
|
union {
|
271
|
-
/**
|
296
|
+
/**
|
297
|
+
* This deallocation callback will be called when the packet is finished
|
272
298
|
* with the buffer if the `move` flags is set.
|
299
|
+
*
|
273
300
|
* If no deallocation callback is `free` will be used.
|
301
|
+
*
|
302
|
+
* Note: `sock` library functions MUST NEVER be called by a callback, or a
|
303
|
+
* deadlock might occur.
|
274
304
|
*/
|
275
305
|
void (*dealloc)(void *buffer);
|
276
|
-
/**
|
306
|
+
/**
|
307
|
+
* This is an alternative deallocation callback accessor (same memory space
|
277
308
|
* as `dealloc`) for conveniently setting the file `close` callback.
|
309
|
+
*
|
310
|
+
* Note: `sock` library functions MUST NEVER be called by a callback, or a
|
311
|
+
* deadlock might occur.
|
278
312
|
*/
|
279
313
|
void (*close)(intptr_t fd);
|
280
314
|
};
|
281
315
|
/** The length (size) of the buffer, or the amount of data to be sent from the
|
282
316
|
* file descriptor.
|
283
317
|
*/
|
284
|
-
|
318
|
+
uintptr_t length;
|
285
319
|
/** Starting point offset from the buffer or file descriptor's beginning. */
|
286
|
-
|
287
|
-
/** When sending data from the memory, using `move` will prevent copy and
|
288
|
-
* memory allocations, moving the memory ownership to the `sock_write2`
|
289
|
-
* function.
|
290
|
-
*/
|
291
|
-
unsigned move : 1;
|
320
|
+
intptr_t offset;
|
292
321
|
/** The packet will be sent as soon as possible. */
|
293
322
|
unsigned urgent : 1;
|
294
323
|
/**
|
@@ -311,189 +340,208 @@ typedef struct {
|
|
311
340
|
} sock_write_info_s;
|
312
341
|
|
313
342
|
void SOCK_DEALLOC_NOOP(void *arg);
|
314
|
-
#define
|
343
|
+
#define SOCK_CLOSE_NOOP ((void (*)(intptr_t))SOCK_DEALLOC_NOOP)
|
315
344
|
|
316
345
|
/**
|
317
|
-
`sock_write2_fn` is the actual function behind the macro `sock_write2`.
|
318
|
-
*/
|
346
|
+
* `sock_write2_fn` is the actual function behind the macro `sock_write2`.
|
347
|
+
*/
|
319
348
|
ssize_t sock_write2_fn(sock_write_info_s options);
|
320
349
|
|
321
350
|
/**
|
322
|
-
`sock_write2` is similar to `sock_write`, except special properties can be
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
351
|
+
* `sock_write2` is similar to `sock_write`, except special properties can be
|
352
|
+
* set.
|
353
|
+
*
|
354
|
+
* On error, -1 will be returned. Otherwise returns 0. All the bytes are
|
355
|
+
* transferred to the socket's user level buffer.
|
356
|
+
*/
|
327
357
|
#define sock_write2(...) sock_write2_fn((sock_write_info_s){__VA_ARGS__})
|
328
358
|
/**
|
329
|
-
`sock_write`
|
330
|
-
|
331
|
-
|
332
|
-
The data isn't necessarily written to the socket and multiple calls to
|
333
|
-
`sock_flush` might be required before all the data is actually sent.
|
334
|
-
|
335
|
-
On error, -1 will be returned. Otherwise returns 0. All the bytes are
|
336
|
-
transferred to the socket's user level buffer.
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
359
|
+
* `sock_write` copies `legnth` data from the buffer and schedules the data to
|
360
|
+
* be sent over the socket.
|
361
|
+
*
|
362
|
+
* The data isn't necessarily written to the socket and multiple calls to
|
363
|
+
* `sock_flush` might be required before all the data is actually sent.
|
364
|
+
*
|
365
|
+
* On error, -1 will be returned. Otherwise returns 0. All the bytes are
|
366
|
+
* transferred to the socket's user level buffer.
|
367
|
+
*
|
368
|
+
* Returns the same values as `sock_write2`.
|
369
|
+
*/
|
370
|
+
// ssize_t sock_write(uintptr_t uuid, void *buffer, size_t legnth);
|
371
|
+
UNUSED_FUNC static inline ssize_t
|
372
|
+
sock_write(const intptr_t uuid, const void *buffer, const size_t length) {
|
373
|
+
if (!length || !buffer)
|
374
|
+
return 0;
|
375
|
+
void *cpy = malloc(length);
|
376
|
+
if (!cpy)
|
377
|
+
return -1;
|
378
|
+
memcpy(cpy, buffer, length);
|
379
|
+
return sock_write2(.uuid = uuid, .buffer = cpy, .length = length);
|
380
|
+
}
|
343
381
|
|
344
382
|
/**
|
345
|
-
Sends data from a file as if it were a single atomic packet (sends up to
|
346
|
-
length bytes or until EOF is reached).
|
347
|
-
|
348
|
-
Once the file was sent, the `source_fd` will be closed using `close`.
|
349
|
-
|
350
|
-
The file will be buffered to the socket chunk by chunk, so that memory
|
351
|
-
consumption is capped. The system's `sendfile` might be used if conditions
|
352
|
-
permit.
|
353
|
-
|
354
|
-
`offset` dictates the starting point for te data to be sent and length sets
|
355
|
-
the maximum amount of data to be sent.
|
356
|
-
|
357
|
-
Returns -1 and closes the file on error. Returns 0 on success.
|
358
|
-
*/
|
383
|
+
* Sends data from a file as if it were a single atomic packet (sends up to
|
384
|
+
* length bytes or until EOF is reached).
|
385
|
+
*
|
386
|
+
* Once the file was sent, the `source_fd` will be closed using `close`.
|
387
|
+
*
|
388
|
+
* The file will be buffered to the socket chunk by chunk, so that memory
|
389
|
+
* consumption is capped. The system's `sendfile` might be used if conditions
|
390
|
+
* permit.
|
391
|
+
*
|
392
|
+
* `offset` dictates the starting point for te data to be sent and length sets
|
393
|
+
* the maximum amount of data to be sent.
|
394
|
+
*
|
395
|
+
* Returns -1 and closes the file on error. Returns 0 on success.
|
396
|
+
*/
|
359
397
|
UNUSED_FUNC static inline ssize_t
|
360
398
|
sock_sendfile(intptr_t uuid, intptr_t source_fd, off_t offset, size_t length) {
|
361
399
|
return sock_write2(.uuid = uuid, .buffer = (void *)(source_fd),
|
362
|
-
.length = length, .is_fd = 1, .offset = offset
|
400
|
+
.length = length, .is_fd = 1, .offset = offset);
|
363
401
|
}
|
364
402
|
|
365
403
|
/**
|
366
|
-
`
|
367
|
-
|
368
|
-
|
404
|
+
* `sock_close` marks the connection for disconnection once all the data was
|
405
|
+
* sent. The actual disconnection will be managed by the `sock_flush` function.
|
406
|
+
*
|
407
|
+
* `sock_flash` will automatically be called.
|
408
|
+
*/
|
409
|
+
void sock_close(intptr_t uuid);
|
369
410
|
|
370
|
-
Return value: 0 will be returned on success and -1 will be returned on an error
|
371
|
-
or when the connection is closed.
|
372
|
-
*/
|
373
|
-
ssize_t sock_flush(intptr_t uuid);
|
374
|
-
/**
|
375
|
-
`sock_flush_strong` performs the same action as `sock_flush` but returns only
|
376
|
-
after all the data was sent. This is a "busy" wait, polling isn't performed.
|
377
|
-
*/
|
378
|
-
void sock_flush_strong(intptr_t uuid);
|
379
411
|
/**
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
The actual disconnection will be managed by the `sock_flush` function.
|
412
|
+
* `sock_force_close` closes the connection immediately, without adhering to any
|
413
|
+
* protocol restrictions and without sending any remaining data in the
|
414
|
+
* connection buffer.
|
415
|
+
*/
|
416
|
+
void sock_force_close(intptr_t uuid);
|
386
417
|
|
387
|
-
`sock_flash` will automatically be called.
|
388
|
-
*/
|
389
|
-
void sock_close(intptr_t uuid);
|
390
418
|
/**
|
391
|
-
`
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
419
|
+
* `sock_hijack` is the reverse of the `sock_open` function, removing the
|
420
|
+
* connection from the `sock` library and clearing it's data without closing it
|
421
|
+
* (`sock_on_close` will NOT be called).
|
422
|
+
*
|
423
|
+
* Returns the original `fd` for the socket. On error returns -1.
|
424
|
+
*/
|
425
|
+
int sock_hijack(intptr_t uuid);
|
396
426
|
|
397
427
|
/* *****************************************************************************
|
398
428
|
Direct user level buffer API.
|
399
|
-
|
400
|
-
The following API allows data to be written directly to the packet, minimizing
|
401
|
-
memory copy operations.
|
402
429
|
*/
|
403
430
|
|
404
431
|
/**
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
uint8_t buf[BUFFER_PACKET_SIZE];
|
415
|
-
} sock_buffer_s;
|
432
|
+
* `sock_flush` writes the data in the internal buffer to the underlying file
|
433
|
+
* descriptor and closes the underlying fd once it's marked for closure (and all
|
434
|
+
* the data was sent).
|
435
|
+
*
|
436
|
+
* Return values: 1 will be returned if `sock_flush` should be called again. 0
|
437
|
+
* will be returned if the socket was fully flushed. -1 will be returned on an
|
438
|
+
* error or when the connection is closed.
|
439
|
+
*/
|
440
|
+
ssize_t sock_flush(intptr_t uuid);
|
416
441
|
|
417
442
|
/**
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
using the `sock_buffer_*` functions.
|
423
|
-
|
424
|
-
Every checked out buffer packet comes with an attached buffer of
|
425
|
-
BUFFER_PACKET_SIZE bytes. This buffer is accessible using the `->buf`
|
426
|
-
pointer.
|
443
|
+
* `sock_flush_strong` performs the same action as `sock_flush` but returns only
|
444
|
+
* after all the data was sent. This is a "busy" wait, polling isn't performed.
|
445
|
+
*/
|
446
|
+
void sock_flush_strong(intptr_t uuid);
|
427
447
|
|
428
|
-
This attached buffer's memory is automatically manages as long as the
|
429
|
-
`sock_buffer_send` or `sock_buffer_free` functions are called.
|
430
|
-
*/
|
431
|
-
sock_buffer_s *sock_buffer_checkout(void);
|
432
448
|
/**
|
433
|
-
|
434
|
-
|
449
|
+
* Calls `sock_flush` for each file descriptor that's buffer isn't empty.
|
450
|
+
*/
|
451
|
+
void sock_flush_all(void);
|
435
452
|
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
453
|
+
/**
|
454
|
+
* Returns the number of `sock_write` calls that are waiting in the socket's
|
455
|
+
* queue and haven't been processed.
|
456
|
+
*
|
457
|
+
* This method will be deprecated in the 0.7.0 release. Use `sock_pending`
|
458
|
+
* instead.
|
459
|
+
*/
|
460
|
+
int __attribute__((deprecated("use sock_pending instead")))
|
461
|
+
sock_has_pending(intptr_t uuid);
|
440
462
|
|
441
463
|
/**
|
442
|
-
Returns
|
443
|
-
|
444
|
-
*/
|
445
|
-
|
464
|
+
* Returns the number of `sock_write` calls that are waiting in the socket's
|
465
|
+
* queue and haven't been processed.
|
466
|
+
*/
|
467
|
+
size_t sock_pending(intptr_t uuid);
|
446
468
|
|
447
469
|
/**
|
448
|
-
|
449
|
-
|
450
|
-
*/
|
451
|
-
void
|
470
|
+
* This weak function can be overwritten when using the `defer` library.
|
471
|
+
* However, the function MUST call {sock_flush} at some point.
|
472
|
+
*/
|
473
|
+
void sock_flush_defer(void *arg, void *ignored);
|
452
474
|
|
453
475
|
/* *****************************************************************************
|
454
476
|
TLC - Transport Layer Callback.
|
455
|
-
|
456
|
-
Experimental
|
457
477
|
*/
|
458
478
|
|
459
479
|
/**
|
460
|
-
The following struct is used for setting a the read/write hooks that will
|
461
|
-
replace the default system calls to `recv` and `write`.
|
480
|
+
* The following struct is used for setting a the read/write hooks that will
|
481
|
+
* replace the default system calls to `recv` and `write`.
|
482
|
+
*
|
483
|
+
* Note: `sock` library functions MUST NEVER be called by any callback, or a
|
484
|
+
* deadlock might occur.
|
485
|
+
*/
|
462
486
|
typedef struct sock_rw_hook_s {
|
463
|
-
/**
|
464
|
-
*
|
465
|
-
|
466
|
-
|
467
|
-
* `
|
468
|
-
|
469
|
-
|
487
|
+
/**
|
488
|
+
* Implement reading from a file descriptor. Should behave like the file
|
489
|
+
* system `read` call, including the setup or errno to EAGAIN / EWOULDBLOCK.
|
490
|
+
*
|
491
|
+
* Note: `sock` library functions MUST NEVER be called by any callback, or a
|
492
|
+
* deadlock might occur.
|
493
|
+
*/
|
494
|
+
ssize_t (*read)(intptr_t uuid, void *udata, void *buf, size_t count);
|
495
|
+
/**
|
496
|
+
* Implement writing to a file descriptor. Should behave like the file system
|
497
|
+
* `write` call.
|
498
|
+
*
|
499
|
+
* Note: `sock` library functions MUST NEVER be called by any callback, or a
|
500
|
+
* deadlock might occur.
|
501
|
+
*/
|
502
|
+
ssize_t (*write)(intptr_t uuid, void *udata, const void *buf, size_t count);
|
503
|
+
/**
|
504
|
+
* When implemented, this function will be called to flush any data remaining
|
470
505
|
* in the internal buffer.
|
506
|
+
*
|
471
507
|
* The function should return the number of bytes remaining in the internal
|
472
508
|
* buffer (0 is a valid response) on -1 (on error).
|
509
|
+
*
|
473
510
|
* It is important thet the `flush` function write to the underlying fd until
|
474
|
-
* the
|
475
|
-
*
|
511
|
+
* the writing operation returns -1 with EWOULDBLOCK or all the data was
|
512
|
+
* written.
|
513
|
+
*
|
514
|
+
* Note: `sock` library functions MUST NEVER be called by any callback, or a
|
515
|
+
* deadlock might occur.
|
476
516
|
*/
|
477
|
-
ssize_t (*flush)(intptr_t
|
478
|
-
/**
|
517
|
+
ssize_t (*flush)(intptr_t uuid, void *udata);
|
518
|
+
/**
|
519
|
+
* The `on_close` callback is called when the socket is closed, allowing for
|
479
520
|
* dynamic sock_rw_hook_s memory management.
|
480
521
|
*
|
481
522
|
* The `on_close` callback should manage is own thread safety mechanism, if
|
482
|
-
* required.
|
483
|
-
|
523
|
+
* required.
|
524
|
+
*
|
525
|
+
* Note: `sock` library functions MUST NEVER be called by any callback, or a
|
526
|
+
* deadlock might occur.
|
527
|
+
* */
|
528
|
+
void (*on_close)(intptr_t uuid, struct sock_rw_hook_s *rw_hook, void *udata);
|
484
529
|
} sock_rw_hook_s;
|
485
530
|
|
486
531
|
/* *****************************************************************************
|
487
532
|
RW hooks implementation
|
488
533
|
*/
|
489
534
|
|
535
|
+
/** Sets a socket hook state (a pointer to the struct). */
|
536
|
+
int sock_rw_hook_set(intptr_t uuid, sock_rw_hook_s *rw_hooks, void *udata);
|
537
|
+
|
490
538
|
/** Gets a socket hook state (a pointer to the struct). */
|
491
|
-
struct sock_rw_hook_s *sock_rw_hook_get(intptr_t
|
539
|
+
struct sock_rw_hook_s *sock_rw_hook_get(intptr_t uuid);
|
492
540
|
|
493
|
-
/**
|
494
|
-
|
541
|
+
/** Returns the socket's udata associated with the read/write hook. */
|
542
|
+
void *sock_rw_udata(intptr_t uuid);
|
495
543
|
|
496
|
-
/** The default Read/Write hooks used for system Read/Write */
|
544
|
+
/** The default Read/Write hooks used for system Read/Write (udata == NULL). */
|
497
545
|
extern const sock_rw_hook_s SOCK_DEFAULT_HOOKS;
|
498
546
|
|
499
547
|
/* *****************************************************************************
|