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.

Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/CHANGELOG.md +22 -0
  4. data/LIMITS.md +19 -9
  5. data/README.md +92 -77
  6. data/SPEC-PubSub-Draft.md +113 -0
  7. data/SPEC-Websocket-Draft.md +127 -143
  8. data/bin/http-hello +0 -1
  9. data/bin/raw-rbhttp +1 -1
  10. data/bin/raw_broadcast +8 -10
  11. data/bin/updated api +2 -2
  12. data/bin/ws-broadcast +2 -4
  13. data/bin/ws-echo +2 -2
  14. data/examples/config.ru +13 -13
  15. data/examples/echo.ru +5 -6
  16. data/examples/hello.ru +2 -3
  17. data/examples/info.md +316 -0
  18. data/examples/pubsub_engine.ru +81 -0
  19. data/examples/redis.ru +9 -9
  20. data/examples/shootout.ru +45 -11
  21. data/ext/iodine/defer.c +194 -297
  22. data/ext/iodine/defer.h +61 -53
  23. data/ext/iodine/evio.c +0 -260
  24. data/ext/iodine/evio.h +50 -22
  25. data/ext/iodine/evio_callbacks.c +26 -0
  26. data/ext/iodine/evio_epoll.c +251 -0
  27. data/ext/iodine/evio_kqueue.c +193 -0
  28. data/ext/iodine/extconf.rb +1 -1
  29. data/ext/iodine/facil.c +1420 -542
  30. data/ext/iodine/facil.h +151 -64
  31. data/ext/iodine/fio_ary.h +418 -0
  32. data/ext/iodine/{base64.c → fio_base64.c} +33 -24
  33. data/ext/iodine/{base64.h → fio_base64.h} +6 -7
  34. data/ext/iodine/{fio_cli_helper.c → fio_cli.c} +77 -58
  35. data/ext/iodine/{fio_cli_helper.h → fio_cli.h} +9 -4
  36. data/ext/iodine/fio_hashmap.h +759 -0
  37. data/ext/iodine/fio_json_parser.h +651 -0
  38. data/ext/iodine/fio_llist.h +257 -0
  39. data/ext/iodine/fio_mem.c +672 -0
  40. data/ext/iodine/fio_mem.h +140 -0
  41. data/ext/iodine/fio_random.c +248 -0
  42. data/ext/iodine/{random.h → fio_random.h} +11 -14
  43. data/ext/iodine/{sha1.c → fio_sha1.c} +28 -24
  44. data/ext/iodine/{sha1.h → fio_sha1.h} +38 -16
  45. data/ext/iodine/{sha2.c → fio_sha2.c} +66 -49
  46. data/ext/iodine/{sha2.h → fio_sha2.h} +57 -26
  47. data/ext/iodine/{fiobj_internal.c → fio_siphash.c} +9 -90
  48. data/ext/iodine/fio_siphash.h +18 -0
  49. data/ext/iodine/fio_tmpfile.h +38 -0
  50. data/ext/iodine/fiobj.h +24 -7
  51. data/ext/iodine/fiobj4sock.h +23 -0
  52. data/ext/iodine/fiobj_ary.c +143 -226
  53. data/ext/iodine/fiobj_ary.h +17 -16
  54. data/ext/iodine/fiobj_data.c +1160 -0
  55. data/ext/iodine/fiobj_data.h +164 -0
  56. data/ext/iodine/fiobj_hash.c +298 -406
  57. data/ext/iodine/fiobj_hash.h +101 -54
  58. data/ext/iodine/fiobj_json.c +478 -601
  59. data/ext/iodine/fiobj_json.h +34 -9
  60. data/ext/iodine/fiobj_numbers.c +383 -51
  61. data/ext/iodine/fiobj_numbers.h +87 -11
  62. data/ext/iodine/fiobj_str.c +423 -184
  63. data/ext/iodine/fiobj_str.h +81 -32
  64. data/ext/iodine/fiobject.c +273 -522
  65. data/ext/iodine/fiobject.h +477 -112
  66. data/ext/iodine/http.c +2243 -83
  67. data/ext/iodine/http.h +842 -121
  68. data/ext/iodine/http1.c +810 -385
  69. data/ext/iodine/http1.h +16 -39
  70. data/ext/iodine/http1_parser.c +146 -74
  71. data/ext/iodine/http1_parser.h +15 -4
  72. data/ext/iodine/http_internal.c +1258 -0
  73. data/ext/iodine/http_internal.h +226 -0
  74. data/ext/iodine/http_mime_parser.h +341 -0
  75. data/ext/iodine/iodine.c +86 -68
  76. data/ext/iodine/iodine.h +26 -11
  77. data/ext/iodine/iodine_helpers.c +8 -7
  78. data/ext/iodine/iodine_http.c +487 -324
  79. data/ext/iodine/iodine_json.c +304 -0
  80. data/ext/iodine/iodine_json.h +6 -0
  81. data/ext/iodine/iodine_protocol.c +107 -45
  82. data/ext/iodine/iodine_pubsub.c +526 -225
  83. data/ext/iodine/iodine_pubsub.h +10 -0
  84. data/ext/iodine/iodine_websockets.c +268 -510
  85. data/ext/iodine/iodine_websockets.h +2 -4
  86. data/ext/iodine/pubsub.c +726 -432
  87. data/ext/iodine/pubsub.h +85 -103
  88. data/ext/iodine/rb-call.c +4 -4
  89. data/ext/iodine/rb-defer.c +46 -22
  90. data/ext/iodine/rb-fiobj2rb.h +117 -0
  91. data/ext/iodine/rb-rack-io.c +73 -238
  92. data/ext/iodine/rb-rack-io.h +2 -2
  93. data/ext/iodine/rb-registry.c +35 -93
  94. data/ext/iodine/rb-registry.h +1 -0
  95. data/ext/iodine/redis_engine.c +742 -304
  96. data/ext/iodine/redis_engine.h +42 -39
  97. data/ext/iodine/resp_parser.h +311 -0
  98. data/ext/iodine/sock.c +627 -490
  99. data/ext/iodine/sock.h +345 -297
  100. data/ext/iodine/spnlock.inc +15 -4
  101. data/ext/iodine/websocket_parser.h +16 -20
  102. data/ext/iodine/websockets.c +188 -257
  103. data/ext/iodine/websockets.h +24 -133
  104. data/lib/iodine.rb +52 -7
  105. data/lib/iodine/cli.rb +6 -24
  106. data/lib/iodine/json.rb +40 -0
  107. data/lib/iodine/version.rb +1 -1
  108. data/lib/iodine/websocket.rb +5 -3
  109. data/lib/rack/handler/iodine.rb +58 -13
  110. metadata +38 -48
  111. data/bin/ws-shootout +0 -107
  112. data/examples/broadcast.ru +0 -56
  113. data/ext/iodine/bscrypt-common.h +0 -116
  114. data/ext/iodine/bscrypt.h +0 -49
  115. data/ext/iodine/fio2resp.c +0 -60
  116. data/ext/iodine/fio2resp.h +0 -51
  117. data/ext/iodine/fio_dict.c +0 -446
  118. data/ext/iodine/fio_dict.h +0 -99
  119. data/ext/iodine/fio_hash_table.h +0 -370
  120. data/ext/iodine/fio_list.h +0 -111
  121. data/ext/iodine/fiobj_internal.h +0 -280
  122. data/ext/iodine/fiobj_primitives.c +0 -131
  123. data/ext/iodine/fiobj_primitives.h +0 -55
  124. data/ext/iodine/fiobj_sym.c +0 -135
  125. data/ext/iodine/fiobj_sym.h +0 -60
  126. data/ext/iodine/hex.c +0 -124
  127. data/ext/iodine/hex.h +0 -70
  128. data/ext/iodine/http1_request.c +0 -81
  129. data/ext/iodine/http1_request.h +0 -58
  130. data/ext/iodine/http1_response.c +0 -417
  131. data/ext/iodine/http1_response.h +0 -95
  132. data/ext/iodine/http_request.c +0 -111
  133. data/ext/iodine/http_request.h +0 -102
  134. data/ext/iodine/http_response.c +0 -1703
  135. data/ext/iodine/http_response.h +0 -250
  136. data/ext/iodine/misc.c +0 -182
  137. data/ext/iodine/misc.h +0 -74
  138. data/ext/iodine/random.c +0 -208
  139. data/ext/iodine/redis_connection.c +0 -278
  140. data/ext/iodine/redis_connection.h +0 -86
  141. data/ext/iodine/resp.c +0 -842
  142. data/ext/iodine/resp.h +0 -261
  143. data/ext/iodine/siphash.c +0 -154
  144. data/ext/iodine/siphash.h +0 -22
  145. data/ext/iodine/xor-crypt.c +0 -193
  146. 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 3
11
- #define LIB_SOCK_VERSION_PATCH 2
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 buffer,
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 will
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
- #ifndef UNUSED_FUNC
38
- #define UNUSED_FUNC __attribute__((unused))
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
- User land buffer settings for every packet's pre-alocated memory size (17Kb)
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) ((intptr_t)((uintptr_t)uuid >> 8))
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 sock_API.
77
+ Process wide and helper sock API.
73
78
  */
74
79
 
75
- /**
76
- Sets a socket to non blocking state.
80
+ /** MUST be called after forking a process. */
81
+ void sock_on_fork(void);
77
82
 
78
- This function is called automatically for the new socket, when using
79
- `sock_accept` or `sock_connect`.
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 sock_API.
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
- Returns -1 on error. Returns a valid socket (non-random) UUID.
100
-
101
- UUIDs with values less then -1 are valid values, depending on the system's
102
- byte-ordering.
103
-
104
- Socket UUIDs are predictable and shouldn't be used outside the local system.
105
- They protect against connection mixups on concurrent systems (i.e. when saving
106
- client data for "broadcasting" or when an old client task is preparing a
107
- response in the background while a disconnection and a new connection occur on
108
- the same `fd`).
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 `libreact`, remember to call `int reactor_add(intptr_t uuid);` to
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
- Returns -1 on error. Returns a valid socket (non-random) UUID.
135
-
136
- Socket UUIDs are predictable and shouldn't be used outside the local system.
137
- They protect against connection mixups on concurrent systems (i.e. when saving
138
- client data for "broadcasting" or when an old client task is preparing a
139
- response in the background while a disconnection and a new connection occur on
140
- the same `fd`).
141
-
142
- When using `evio`, remember to call `int evio_add(sock_fd2uuid(uuid),
143
- (void*)uuid);` to listen for events.
144
-
145
- NOTICE:
146
-
147
- This function is non-blocking, meaning that the connection probably wasn't
148
- established by the time the function returns (this prevents the function from
149
- hanging while waiting for a network timeout).
150
-
151
- Use select, poll, `evio` or other solutions to review the connection state
152
- before attempting to write to the socket.
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 `sock_API` calls, returning a valid UUID.
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 not.
203
+ Returns 0 if the socket is valid, open and isn't flagged to be closed.
181
204
  */
182
- int sock_isvalid(intptr_t uuid);
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
- /** Returns the information available about the socket's peer address.
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 fd
207
- will result in the registry being updated and the fd being closed.
208
-
209
- Returns -1 on error. Returns a valid socket (non-random) UUID.
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 timeout
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 in
233
- the buffer is sent. This function will be called only one the connection is
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 buffer
243
- starting at buf.
244
-
245
- `sock_read`'s return values are wildly different then the native return values
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 the
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 be
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
- /** This deallocation callback will be called when the packet is finished
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
- /** This is an alternative deallocation callback accessor (same memory space
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
- size_t length;
318
+ uintptr_t length;
285
319
  /** Starting point offset from the buffer or file descriptor's beginning. */
286
- off_t offset;
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 SOCK_DEALLOC_NOOP SOCK_DEALLOC_NOOP
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 set.
323
-
324
- On error, -1 will be returned. Otherwise returns 0. All the bytes are
325
- transferred to the socket's user level buffer.
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` writes up to count bytes from the buffer pointed `buf` to the
330
- buffer associated with the socket `sockfd`.
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
- **Note** this is actually a specific case of `sock_write2` and this macro
339
- actually calls `sock_write2`.
340
- */
341
- #define sock_write(sock_uuid, buf, count) \
342
- sock_write2(.uuid = (sock_uuid), .buffer = (buf), .length = (count))
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, .move = 1);
400
+ .length = length, .is_fd = 1, .offset = offset);
363
401
  }
364
402
 
365
403
  /**
366
- `sock_flush` writes the data in the internal buffer to the underlying file
367
- descriptor and closes the underlying fd once it's marked for closure (and all
368
- the data was sent).
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
- Calls `sock_flush` for each file descriptor that's buffer isn't empty.
381
- */
382
- void sock_flush_all(void);
383
- /**
384
- `sock_close` marks the connection for disconnection once all the data was sent.
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
- `sock_force_close` closes the connection immediately, without adhering to any
392
- protocol restrictions and without sending any remaining data in the connection
393
- buffer.
394
- */
395
- void sock_force_close(intptr_t uuid);
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
- The buffer of a user-land sock-packet.
406
-
407
- Remember to set the correct `len` value, so the full amount of the data is sent.
408
-
409
- See `sock_buffer_checkout`, `sock_buffer_send` and `sock_buffer_free` for more
410
- information.
411
- */
412
- typedef struct sock_buffer_s {
413
- size_t len;
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
- Checks out a `sock_buffer_s` from the buffer pool.
419
-
420
- This function will hang until a buffer becomes available, so never check out
421
- more then a single buffer at a time and remember to free or send the buffer
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
- Attaches a packet to a socket's output buffer and calls `sock_flush` for the
434
- socket.
449
+ * Calls `sock_flush` for each file descriptor that's buffer isn't empty.
450
+ */
451
+ void sock_flush_all(void);
435
452
 
436
- Returns -1 on error. Returns 0 on success. The `buffer` memory is always
437
- automatically managed.
438
- */
439
- ssize_t sock_buffer_send(intptr_t uuid, sock_buffer_s *buffer);
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 TRUE (non 0) if there is data waiting to be written to the socket in the
443
- user-land buffer.
444
- */
445
- int sock_has_pending(intptr_t uuid);
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
- Use `sock_buffer_free` to free unused buffers that were checked-out using
449
- `sock_buffer_checkout`.
450
- */
451
- void sock_buffer_free(sock_buffer_s *buffer);
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
- /** Implement reading from a file descriptor. Should behave like the file
464
- * system `read` call, including the setup or errno to EAGAIN / EWOULDBLOCK.*/
465
- ssize_t (*read)(intptr_t uuid, void *buf, size_t count);
466
- /** Implement writing to a file descriptor. Should behave like the file system
467
- * `write` call.*/
468
- ssize_t (*write)(intptr_t uuid, const void *buf, size_t count);
469
- /** When implemented, this function will be called to flush any data remaining
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
- * writing operation returns -1 with EWOULDBLOCK or all the data was written.
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 fduuid);
478
- /** The `on_close` callback is called when the socket is closed, allowing for
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
- void (*on_close)(intptr_t fduuid, struct sock_rw_hook_s *rw_hook);
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 fduuid);
539
+ struct sock_rw_hook_s *sock_rw_hook_get(intptr_t uuid);
492
540
 
493
- /** Sets a socket hook state (a pointer to the struct). */
494
- int sock_rw_hook_set(intptr_t fduuid, sock_rw_hook_s *rw_hooks);
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
  /* *****************************************************************************