/src/uWebSockets/uSockets/src/context.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Authored by Alex Hultman, 2018-2019. |
3 | | * Intellectual property of third-party. |
4 | | |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at |
8 | | |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | |
18 | | #ifndef LIBUS_USE_IO_URING |
19 | | |
20 | | #include "libusockets.h" |
21 | | #include "internal/internal.h" |
22 | | #include <stdlib.h> |
23 | | #include <string.h> |
24 | | |
25 | 905k | int default_is_low_prio_handler(struct us_socket_t *s) { |
26 | 905k | return 0; |
27 | 905k | } |
28 | | |
29 | | /* Shared with SSL */ |
30 | | |
31 | 0 | unsigned short us_socket_context_timestamp(int ssl, struct us_socket_context_t *context) { |
32 | 0 | return context->timestamp; |
33 | 0 | } |
34 | | |
35 | 5.93k | void us_listen_socket_close(int ssl, struct us_listen_socket_t *ls) { |
36 | | /* us_listen_socket_t extends us_socket_t so we close in similar ways */ |
37 | 5.93k | if (!us_socket_is_closed(0, &ls->s)) { |
38 | 5.93k | us_internal_socket_context_unlink_listen_socket(ls->s.context, ls); |
39 | 5.93k | us_poll_stop((struct us_poll_t *) &ls->s, ls->s.context->loop); |
40 | 5.93k | bsd_close_socket(us_poll_fd((struct us_poll_t *) &ls->s)); |
41 | | |
42 | | /* Link this socket to the close-list and let it be deleted after this iteration */ |
43 | 5.93k | ls->s.next = ls->s.context->loop->data.closed_head; |
44 | 5.93k | ls->s.context->loop->data.closed_head = &ls->s; |
45 | | |
46 | | /* Any socket with prev = context is marked as closed */ |
47 | 5.93k | ls->s.prev = (struct us_socket_t *) ls->s.context; |
48 | 5.93k | } |
49 | | |
50 | | /* We cannot immediately free a listen socket as we can be inside an accept loop */ |
51 | 5.93k | } |
52 | | |
53 | 0 | void us_socket_context_close(int ssl, struct us_socket_context_t *context) { |
54 | | /* Begin by closing all listen sockets */ |
55 | 0 | struct us_listen_socket_t *ls = context->head_listen_sockets; |
56 | 0 | while (ls) { |
57 | 0 | struct us_listen_socket_t *nextLS = (struct us_listen_socket_t *) ls->s.next; |
58 | 0 | us_listen_socket_close(ssl, ls); |
59 | 0 | ls = nextLS; |
60 | 0 | } |
61 | | |
62 | | /* Then close all regular sockets */ |
63 | 0 | struct us_socket_t *s = context->head_sockets; |
64 | 0 | while (s) { |
65 | 0 | struct us_socket_t *nextS = s->next; |
66 | 0 | us_socket_close(ssl, s, 0, 0); |
67 | 0 | s = nextS; |
68 | 0 | } |
69 | 0 | } |
70 | | |
71 | 5.93k | void us_internal_socket_context_unlink_listen_socket(struct us_socket_context_t *context, struct us_listen_socket_t *ls) { |
72 | | /* We have to properly update the iterator used to sweep sockets for timeouts */ |
73 | 5.93k | if (ls == (struct us_listen_socket_t *) context->iterator) { |
74 | 0 | context->iterator = ls->s.next; |
75 | 0 | } |
76 | | |
77 | 5.93k | if (ls->s.prev == ls->s.next) { |
78 | 5.93k | context->head_listen_sockets = 0; |
79 | 5.93k | } else { |
80 | 0 | if (ls->s.prev) { |
81 | 0 | ls->s.prev->next = ls->s.next; |
82 | 0 | } else { |
83 | 0 | context->head_listen_sockets = (struct us_listen_socket_t *) ls->s.next; |
84 | 0 | } |
85 | 0 | if (ls->s.next) { |
86 | 0 | ls->s.next->prev = ls->s.prev; |
87 | 0 | } |
88 | 0 | } |
89 | 5.93k | } |
90 | | |
91 | 1.12M | void us_internal_socket_context_unlink_socket(struct us_socket_context_t *context, struct us_socket_t *s) { |
92 | | /* We have to properly update the iterator used to sweep sockets for timeouts */ |
93 | 1.12M | if (s == context->iterator) { |
94 | 11.0k | context->iterator = s->next; |
95 | 11.0k | } |
96 | | |
97 | 1.12M | if (s->prev == s->next) { |
98 | 262k | context->head_sockets = 0; |
99 | 863k | } else { |
100 | 863k | if (s->prev) { |
101 | 559k | s->prev->next = s->next; |
102 | 559k | } else { |
103 | 303k | context->head_sockets = s->next; |
104 | 303k | } |
105 | 863k | if (s->next) { |
106 | 835k | s->next->prev = s->prev; |
107 | 835k | } |
108 | 863k | } |
109 | 1.12M | } |
110 | | |
111 | | /* We always add in the top, so we don't modify any s.next */ |
112 | 5.93k | void us_internal_socket_context_link_listen_socket(struct us_socket_context_t *context, struct us_listen_socket_t *ls) { |
113 | 5.93k | ls->s.context = context; |
114 | 5.93k | ls->s.next = (struct us_socket_t *) context->head_listen_sockets; |
115 | 5.93k | ls->s.prev = 0; |
116 | 5.93k | if (context->head_listen_sockets) { |
117 | 0 | context->head_listen_sockets->s.prev = &ls->s; |
118 | 0 | } |
119 | 5.93k | context->head_listen_sockets = ls; |
120 | 5.93k | } |
121 | | |
122 | | /* We always add in the top, so we don't modify any s.next */ |
123 | 1.12M | void us_internal_socket_context_link_socket(struct us_socket_context_t *context, struct us_socket_t *s) { |
124 | 1.12M | s->context = context; |
125 | 1.12M | s->next = context->head_sockets; |
126 | 1.12M | s->prev = 0; |
127 | 1.12M | if (context->head_sockets) { |
128 | 863k | context->head_sockets->prev = s; |
129 | 863k | } |
130 | 1.12M | context->head_sockets = s; |
131 | 1.12M | } |
132 | | |
133 | 6.60M | struct us_loop_t *us_socket_context_loop(int ssl, struct us_socket_context_t *context) { |
134 | 6.60M | return context->loop; |
135 | 6.60M | } |
136 | | |
137 | | /* Not shared with SSL */ |
138 | | |
139 | | /* Lookup userdata by server name pattern */ |
140 | 0 | void *us_socket_context_find_server_name_userdata(int ssl, struct us_socket_context_t *context, const char *hostname_pattern) { |
141 | | #ifndef LIBUS_NO_SSL |
142 | | if (ssl) { |
143 | | return us_internal_ssl_socket_context_find_server_name_userdata((struct us_internal_ssl_socket_context_t *) context, hostname_pattern); |
144 | | } |
145 | | #endif |
146 | 0 | return NULL; |
147 | 0 | } |
148 | | |
149 | | /* Get userdata attached to this SNI-routed socket, or nullptr if default */ |
150 | 124k | void *us_socket_server_name_userdata(int ssl, struct us_socket_t *s) { |
151 | | #ifndef LIBUS_NO_SSL |
152 | | if (ssl) { |
153 | | return us_internal_ssl_socket_get_sni_userdata((struct us_internal_ssl_socket_t *) s); |
154 | | } |
155 | | #endif |
156 | 124k | return NULL; |
157 | 124k | } |
158 | | |
159 | | /* Add SNI context */ |
160 | 0 | void us_socket_context_add_server_name(int ssl, struct us_socket_context_t *context, const char *hostname_pattern, struct us_socket_context_options_t options, void *user) { |
161 | | #ifndef LIBUS_NO_SSL |
162 | | if (ssl) { |
163 | | us_internal_ssl_socket_context_add_server_name((struct us_internal_ssl_socket_context_t *) context, hostname_pattern, options, user); |
164 | | } |
165 | | #endif |
166 | 0 | } |
167 | | |
168 | | /* Remove SNI context */ |
169 | 0 | void us_socket_context_remove_server_name(int ssl, struct us_socket_context_t *context, const char *hostname_pattern) { |
170 | | #ifndef LIBUS_NO_SSL |
171 | | if (ssl) { |
172 | | us_internal_ssl_socket_context_remove_server_name((struct us_internal_ssl_socket_context_t *) context, hostname_pattern); |
173 | | } |
174 | | #endif |
175 | 0 | } |
176 | | |
177 | | /* I don't like this one - maybe rename it to on_missing_server_name? */ |
178 | | |
179 | | /* Called when SNI matching fails - not if a match could be made. |
180 | | * You may modify the context by adding/removing names in this callback. |
181 | | * If the correct name is added immediately in the callback, it will be used */ |
182 | 0 | void us_socket_context_on_server_name(int ssl, struct us_socket_context_t *context, void (*cb)(struct us_socket_context_t *, const char *hostname)) { |
183 | | #ifndef LIBUS_NO_SSL |
184 | | if (ssl) { |
185 | | us_internal_ssl_socket_context_on_server_name((struct us_internal_ssl_socket_context_t *) context, (void (*)(struct us_internal_ssl_socket_context_t *, const char *hostname)) cb); |
186 | | } |
187 | | #endif |
188 | 0 | } |
189 | | |
190 | | /* Todo: get native context from SNI pattern */ |
191 | | |
192 | 0 | void *us_socket_context_get_native_handle(int ssl, struct us_socket_context_t *context) { |
193 | | #ifndef LIBUS_NO_SSL |
194 | | if (ssl) { |
195 | | return us_internal_ssl_socket_context_get_native_handle((struct us_internal_ssl_socket_context_t *) context); |
196 | | } |
197 | | #endif |
198 | | |
199 | | /* There is no native handle for a non-SSL socket context */ |
200 | 0 | return 0; |
201 | 0 | } |
202 | | |
203 | | /* Options is currently only applicable for SSL - this will change with time (prefer_low_memory is one example) */ |
204 | 11.8k | struct us_socket_context_t *us_create_socket_context(int ssl, struct us_loop_t *loop, int context_ext_size, struct us_socket_context_options_t options) { |
205 | | #ifndef LIBUS_NO_SSL |
206 | | if (ssl) { |
207 | | /* This function will call us, again, with SSL = false and a bigger ext_size */ |
208 | | return (struct us_socket_context_t *) us_internal_create_ssl_socket_context(loop, context_ext_size, options); |
209 | | } |
210 | | #endif |
211 | | |
212 | | /* This path is taken once either way - always BEFORE whatever SSL may do LATER. |
213 | | * context_ext_size will however be modified larger in case of SSL, to hold SSL extensions */ |
214 | | |
215 | 11.8k | struct us_socket_context_t *context = malloc(sizeof(struct us_socket_context_t) + context_ext_size); |
216 | 11.8k | context->loop = loop; |
217 | 11.8k | context->head_sockets = 0; |
218 | 11.8k | context->head_listen_sockets = 0; |
219 | 11.8k | context->iterator = 0; |
220 | 11.8k | context->next = 0; |
221 | 11.8k | context->is_low_prio = default_is_low_prio_handler; |
222 | | |
223 | | /* Begin at 0 */ |
224 | 11.8k | context->timestamp = 0; |
225 | 11.8k | context->long_timestamp = 0; |
226 | 11.8k | context->global_tick = 0; |
227 | | |
228 | | /* Some new events must be set to null for backwards compatibility */ |
229 | 11.8k | context->on_pre_open = 0; |
230 | | |
231 | 11.8k | us_internal_loop_link(loop, context); |
232 | | |
233 | | /* If we are called from within SSL code, SSL code will make further changes to us */ |
234 | 11.8k | return context; |
235 | 11.8k | } |
236 | | |
237 | 11.8k | void us_socket_context_free(int ssl, struct us_socket_context_t *context) { |
238 | | #ifndef LIBUS_NO_SSL |
239 | | if (ssl) { |
240 | | /* This function will call us again with SSL=false */ |
241 | | us_internal_ssl_socket_context_free((struct us_internal_ssl_socket_context_t *) context); |
242 | | return; |
243 | | } |
244 | | #endif |
245 | | |
246 | | /* This path is taken once either way - always AFTER whatever SSL may do BEFORE. |
247 | | * This is the opposite order compared to when creating the context - SSL code is cleaning up before non-SSL */ |
248 | | |
249 | 11.8k | us_internal_loop_unlink(context->loop, context); |
250 | 11.8k | free(context); |
251 | 11.8k | } |
252 | | |
253 | 5.94k | struct us_listen_socket_t *us_socket_context_listen(int ssl, struct us_socket_context_t *context, const char *host, int port, int options, int socket_ext_size) { |
254 | | #ifndef LIBUS_NO_SSL |
255 | | if (ssl) { |
256 | | return us_internal_ssl_socket_context_listen((struct us_internal_ssl_socket_context_t *) context, host, port, options, socket_ext_size); |
257 | | } |
258 | | #endif |
259 | | |
260 | 5.94k | LIBUS_SOCKET_DESCRIPTOR listen_socket_fd = bsd_create_listen_socket(host, port, options); |
261 | | |
262 | 5.94k | if (listen_socket_fd == LIBUS_SOCKET_ERROR) { |
263 | 12 | return 0; |
264 | 12 | } |
265 | | |
266 | 5.93k | struct us_poll_t *p = us_create_poll(context->loop, 0, sizeof(struct us_listen_socket_t) - sizeof(struct us_poll_t)); |
267 | 5.93k | us_poll_init(p, listen_socket_fd, POLL_TYPE_SEMI_SOCKET); |
268 | 5.93k | us_poll_start(p, context->loop, LIBUS_SOCKET_READABLE); |
269 | | |
270 | 5.93k | struct us_listen_socket_t *ls = (struct us_listen_socket_t *) p; |
271 | | |
272 | 5.93k | ls->s.context = context; |
273 | 5.93k | ls->s.timeout = 255; |
274 | 5.93k | ls->s.long_timeout = 255; |
275 | 5.93k | ls->s.low_prio_state = 0; |
276 | 5.93k | ls->s.next = 0; |
277 | 5.93k | us_internal_socket_context_link_listen_socket(context, ls); |
278 | | |
279 | 5.93k | ls->socket_ext_size = socket_ext_size; |
280 | | |
281 | 5.93k | return ls; |
282 | 5.94k | } |
283 | | |
284 | 0 | struct us_listen_socket_t *us_socket_context_listen_unix(int ssl, struct us_socket_context_t *context, const char *path, int options, int socket_ext_size) { |
285 | | #ifndef LIBUS_NO_SSL |
286 | | if (ssl) { |
287 | | return us_internal_ssl_socket_context_listen_unix((struct us_internal_ssl_socket_context_t *) context, path, options, socket_ext_size); |
288 | | } |
289 | | #endif |
290 | |
|
291 | 0 | LIBUS_SOCKET_DESCRIPTOR listen_socket_fd = bsd_create_listen_socket_unix(path, options); |
292 | |
|
293 | 0 | if (listen_socket_fd == LIBUS_SOCKET_ERROR) { |
294 | 0 | return 0; |
295 | 0 | } |
296 | | |
297 | 0 | struct us_poll_t *p = us_create_poll(context->loop, 0, sizeof(struct us_listen_socket_t) - sizeof(struct us_poll_t)); |
298 | 0 | us_poll_init(p, listen_socket_fd, POLL_TYPE_SEMI_SOCKET); |
299 | 0 | us_poll_start(p, context->loop, LIBUS_SOCKET_READABLE); |
300 | |
|
301 | 0 | struct us_listen_socket_t *ls = (struct us_listen_socket_t *) p; |
302 | |
|
303 | 0 | ls->s.context = context; |
304 | 0 | ls->s.timeout = 255; |
305 | 0 | ls->s.long_timeout = 255; |
306 | 0 | ls->s.low_prio_state = 0; |
307 | 0 | ls->s.next = 0; |
308 | 0 | us_internal_socket_context_link_listen_socket(context, ls); |
309 | |
|
310 | 0 | ls->socket_ext_size = socket_ext_size; |
311 | |
|
312 | 0 | return ls; |
313 | 0 | } |
314 | | |
315 | 0 | struct us_socket_t *us_socket_context_connect(int ssl, struct us_socket_context_t *context, const char *host, int port, const char *source_host, int options, int socket_ext_size) { |
316 | | #ifndef LIBUS_NO_SSL |
317 | | if (ssl) { |
318 | | return (struct us_socket_t *) us_internal_ssl_socket_context_connect((struct us_internal_ssl_socket_context_t *) context, host, port, source_host, options, socket_ext_size); |
319 | | } |
320 | | #endif |
321 | |
|
322 | 0 | LIBUS_SOCKET_DESCRIPTOR connect_socket_fd = bsd_create_connect_socket(host, port, source_host, options); |
323 | 0 | if (connect_socket_fd == LIBUS_SOCKET_ERROR) { |
324 | 0 | return 0; |
325 | 0 | } |
326 | | |
327 | | /* Connect sockets are semi-sockets just like listen sockets */ |
328 | 0 | struct us_poll_t *p = us_create_poll(context->loop, 0, sizeof(struct us_socket_t) - sizeof(struct us_poll_t) + socket_ext_size); |
329 | 0 | us_poll_init(p, connect_socket_fd, POLL_TYPE_SEMI_SOCKET); |
330 | 0 | us_poll_start(p, context->loop, LIBUS_SOCKET_WRITABLE); |
331 | |
|
332 | 0 | struct us_socket_t *connect_socket = (struct us_socket_t *) p; |
333 | | |
334 | | /* Link it into context so that timeout fires properly */ |
335 | 0 | connect_socket->context = context; |
336 | 0 | connect_socket->timeout = 255; |
337 | 0 | connect_socket->long_timeout = 255; |
338 | 0 | connect_socket->low_prio_state = 0; |
339 | 0 | us_internal_socket_context_link_socket(context, connect_socket); |
340 | |
|
341 | 0 | return connect_socket; |
342 | 0 | } |
343 | | |
344 | 0 | struct us_socket_t *us_socket_context_connect_unix(int ssl, struct us_socket_context_t *context, const char *server_path, int options, int socket_ext_size) { |
345 | | #ifndef LIBUS_NO_SSL |
346 | | if (ssl) { |
347 | | return (struct us_socket_t *) us_internal_ssl_socket_context_connect_unix((struct us_internal_ssl_socket_context_t *) context, server_path, options, socket_ext_size); |
348 | | } |
349 | | #endif |
350 | |
|
351 | 0 | LIBUS_SOCKET_DESCRIPTOR connect_socket_fd = bsd_create_connect_socket_unix(server_path, options); |
352 | 0 | if (connect_socket_fd == LIBUS_SOCKET_ERROR) { |
353 | 0 | return 0; |
354 | 0 | } |
355 | | |
356 | | /* Connect sockets are semi-sockets just like listen sockets */ |
357 | 0 | struct us_poll_t *p = us_create_poll(context->loop, 0, sizeof(struct us_socket_t) - sizeof(struct us_poll_t) + socket_ext_size); |
358 | 0 | us_poll_init(p, connect_socket_fd, POLL_TYPE_SEMI_SOCKET); |
359 | 0 | us_poll_start(p, context->loop, LIBUS_SOCKET_WRITABLE); |
360 | |
|
361 | 0 | struct us_socket_t *connect_socket = (struct us_socket_t *) p; |
362 | | |
363 | | /* Link it into context so that timeout fires properly */ |
364 | 0 | connect_socket->context = context; |
365 | 0 | connect_socket->timeout = 255; |
366 | 0 | connect_socket->long_timeout = 255; |
367 | 0 | connect_socket->low_prio_state = 0; |
368 | 0 | us_internal_socket_context_link_socket(context, connect_socket); |
369 | |
|
370 | 0 | return connect_socket; |
371 | 0 | } |
372 | | |
373 | 5.94k | struct us_socket_context_t *us_create_child_socket_context(int ssl, struct us_socket_context_t *context, int context_ext_size) { |
374 | | #ifndef LIBUS_NO_SSL |
375 | | if (ssl) { |
376 | | return (struct us_socket_context_t *) us_internal_create_child_ssl_socket_context((struct us_internal_ssl_socket_context_t *) context, context_ext_size); |
377 | | } |
378 | | #endif |
379 | | |
380 | | /* For TCP we simply create a new context as nothing is shared */ |
381 | 5.94k | struct us_socket_context_options_t options = {0}; |
382 | 5.94k | return us_create_socket_context(ssl, context->loop, context_ext_size, options); |
383 | 5.94k | } |
384 | | |
385 | | /* Note: This will set timeout to 0 */ |
386 | 106k | struct us_socket_t *us_socket_context_adopt_socket(int ssl, struct us_socket_context_t *context, struct us_socket_t *s, int ext_size) { |
387 | | #ifndef LIBUS_NO_SSL |
388 | | if (ssl) { |
389 | | return (struct us_socket_t *) us_internal_ssl_socket_context_adopt_socket((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t *) s, ext_size); |
390 | | } |
391 | | #endif |
392 | | |
393 | | /* Cannot adopt a closed socket */ |
394 | 106k | if (us_socket_is_closed(ssl, s)) { |
395 | 0 | return s; |
396 | 0 | } |
397 | | |
398 | 106k | if (s->low_prio_state != 1) { |
399 | | /* This properly updates the iterator if in on_timeout */ |
400 | 106k | us_internal_socket_context_unlink_socket(s->context, s); |
401 | 106k | } |
402 | | |
403 | 106k | struct us_socket_t *new_s = (struct us_socket_t *) us_poll_resize(&s->p, s->context->loop, sizeof(struct us_socket_t) + ext_size); |
404 | 106k | new_s->timeout = 255; |
405 | 106k | new_s->long_timeout = 255; |
406 | | |
407 | 106k | if (new_s->low_prio_state == 1) { |
408 | | /* update pointers in low-priority queue */ |
409 | 0 | if (!new_s->prev) new_s->context->loop->data.low_prio_head = new_s; |
410 | 0 | else new_s->prev->next = new_s; |
411 | |
|
412 | 0 | if (new_s->next) new_s->next->prev = new_s; |
413 | 106k | } else { |
414 | 106k | us_internal_socket_context_link_socket(context, new_s); |
415 | 106k | } |
416 | | |
417 | 106k | return new_s; |
418 | 106k | } |
419 | | |
420 | | /* For backwards compatibility, this function will be set to nullptr by default. */ |
421 | 0 | void us_socket_context_on_pre_open(int ssl, struct us_socket_context_t *context, LIBUS_SOCKET_DESCRIPTOR (*on_pre_open)(struct us_socket_context_t *context, LIBUS_SOCKET_DESCRIPTOR fd)) { |
422 | | /* For this event, there is no difference between SSL and non-SSL */ |
423 | 0 | context->on_pre_open = on_pre_open; |
424 | 0 | } |
425 | | |
426 | 5.94k | void us_socket_context_on_open(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_open)(struct us_socket_t *s, int is_client, char *ip, int ip_length)) { |
427 | | #ifndef LIBUS_NO_SSL |
428 | | if (ssl) { |
429 | | us_internal_ssl_socket_context_on_open((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t * (*)(struct us_internal_ssl_socket_t *, int, char *, int)) on_open); |
430 | | return; |
431 | | } |
432 | | #endif |
433 | | |
434 | 5.94k | context->on_open = on_open; |
435 | 5.94k | } |
436 | | |
437 | 11.8k | void us_socket_context_on_close(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_close)(struct us_socket_t *s, int code, void *reason)) { |
438 | | #ifndef LIBUS_NO_SSL |
439 | | if (ssl) { |
440 | | us_internal_ssl_socket_context_on_close((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t * (*)(struct us_internal_ssl_socket_t *, int code, void *reason)) on_close); |
441 | | return; |
442 | | } |
443 | | #endif |
444 | | |
445 | 11.8k | context->on_close = on_close; |
446 | 11.8k | } |
447 | | |
448 | 11.8k | void us_socket_context_on_data(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_data)(struct us_socket_t *s, char *data, int length)) { |
449 | | #ifndef LIBUS_NO_SSL |
450 | | if (ssl) { |
451 | | us_internal_ssl_socket_context_on_data((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t * (*)(struct us_internal_ssl_socket_t *, char *, int)) on_data); |
452 | | return; |
453 | | } |
454 | | #endif |
455 | | |
456 | 11.8k | context->on_data = on_data; |
457 | 11.8k | } |
458 | | |
459 | 11.8k | void us_socket_context_on_writable(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_writable)(struct us_socket_t *s)) { |
460 | | #ifndef LIBUS_NO_SSL |
461 | | if (ssl) { |
462 | | us_internal_ssl_socket_context_on_writable((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t * (*)(struct us_internal_ssl_socket_t *)) on_writable); |
463 | | return; |
464 | | } |
465 | | #endif |
466 | | |
467 | 11.8k | context->on_writable = on_writable; |
468 | 11.8k | } |
469 | | |
470 | 5.94k | void us_socket_context_on_long_timeout(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_long_timeout)(struct us_socket_t *)) { |
471 | | #ifndef LIBUS_NO_SSL |
472 | | if (ssl) { |
473 | | us_internal_ssl_socket_context_on_long_timeout((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t * (*)(struct us_internal_ssl_socket_t *)) on_long_timeout); |
474 | | return; |
475 | | } |
476 | | #endif |
477 | | |
478 | 5.94k | context->on_socket_long_timeout = on_long_timeout; |
479 | 5.94k | } |
480 | | |
481 | 11.8k | void us_socket_context_on_timeout(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_timeout)(struct us_socket_t *)) { |
482 | | #ifndef LIBUS_NO_SSL |
483 | | if (ssl) { |
484 | | us_internal_ssl_socket_context_on_timeout((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t * (*)(struct us_internal_ssl_socket_t *)) on_timeout); |
485 | | return; |
486 | | } |
487 | | #endif |
488 | | |
489 | 11.8k | context->on_socket_timeout = on_timeout; |
490 | 11.8k | } |
491 | | |
492 | 11.8k | void us_socket_context_on_end(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_end)(struct us_socket_t *)) { |
493 | | #ifndef LIBUS_NO_SSL |
494 | | if (ssl) { |
495 | | us_internal_ssl_socket_context_on_end((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t * (*)(struct us_internal_ssl_socket_t *)) on_end); |
496 | | return; |
497 | | } |
498 | | #endif |
499 | | |
500 | 11.8k | context->on_end = on_end; |
501 | 11.8k | } |
502 | | |
503 | 0 | void us_socket_context_on_connect_error(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_connect_error)(struct us_socket_t *s, int code)) { |
504 | | #ifndef LIBUS_NO_SSL |
505 | | if (ssl) { |
506 | | us_internal_ssl_socket_context_on_connect_error((struct us_internal_ssl_socket_context_t *) context, (struct us_internal_ssl_socket_t * (*)(struct us_internal_ssl_socket_t *, int)) on_connect_error); |
507 | | return; |
508 | | } |
509 | | #endif |
510 | | |
511 | 0 | context->on_connect_error = on_connect_error; |
512 | 0 | } |
513 | | |
514 | 16.1M | void *us_socket_context_ext(int ssl, struct us_socket_context_t *context) { |
515 | | #ifndef LIBUS_NO_SSL |
516 | | if (ssl) { |
517 | | return us_internal_ssl_socket_context_ext((struct us_internal_ssl_socket_context_t *) context); |
518 | | } |
519 | | #endif |
520 | | |
521 | 16.1M | return context + 1; |
522 | 16.1M | } |
523 | | |
524 | | #endif |