Skip to content

Commit d29d5ba

Browse files
Alex HultmanAlex Hultman
authored andcommitted
Initial Rust porting (WIP)
1 parent 5d1d640 commit d29d5ba

9 files changed

Lines changed: 491 additions & 237 deletions

File tree

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
*.h linguist-language=C
2+
examples/* linguist-vendored
3+
misc/* linguist-vendored
4+
tests/* linguist-vendored

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ else
2323
override LDFLAGS += -L/usr/local/lib -lwolfssl
2424
else
2525
override CFLAGS += -DLIBUS_NO_SSL
26+
override RUSTFLAGS += --cfg LIBUS_NO_SSL
2627
endif
2728
endif
2829
endif
2930

3031
# WITH_LIBUV=1 builds with libuv as event-loop
3132
ifeq ($(WITH_LIBUV),1)
3233
override CFLAGS += -DLIBUS_USE_LIBUV
34+
override RUSTFLAGS += --cfg LIBUS_USE_LIBUV
3335
override LDFLAGS += -luv
3436
endif
3537

@@ -57,12 +59,14 @@ ifeq ($(WITH_QUIC),1)
5759
override LDFLAGS += -pthread -lz -lm uSockets.a lsquic/src/liblsquic/liblsquic.a
5860
else
5961
override CFLAGS += -std=c11 -Isrc
60-
override LDFLAGS += uSockets.a
62+
override LDFLAGS += uSockets.a libflush.a
6163
endif
6264

6365
# By default we build the uSockets.a static library
6466
default:
6567
rm -f *.o
68+
# Do require Rust as experiment
69+
rustc $(RUSTFLAGS) src/flush.rs -Clto --crate-type=staticlib -O
6670
$(CC) $(CFLAGS) -O3 -c src/*.c src/eventing/*.c src/crypto/*.c
6771
# Also link in Boost Asio support
6872
ifeq ($(WITH_ASIO),1)
@@ -78,6 +82,7 @@ ifeq ($(WITH_BORINGSSL),1)
7882
endif
7983
# Create a static library (try windows, then unix)
8084
lib.exe /out:uSockets.a *.o || $(AR) rvs uSockets.a *.o
85+
cp flush.lib libflush.a || echo ok
8186

8287
# BoringSSL needs cmake and golang
8388
.PHONY: boringssl

src/bsd.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,6 @@ LIBUS_SOCKET_DESCRIPTOR bsd_create_socket(int domain, int type, int protocol) {
299299
return bsd_set_nonblocking(apple_no_sigpipe(created_fd));
300300
}
301301

302-
void bsd_close_socket(LIBUS_SOCKET_DESCRIPTOR fd) {
303-
#ifdef _WIN32
304-
closesocket(fd);
305-
#else
306-
close(fd);
307-
#endif
308-
}
309-
310302
void bsd_shutdown_socket(LIBUS_SOCKET_DESCRIPTOR fd) {
311303
#ifdef _WIN32
312304
shutdown(fd, SD_SEND);
@@ -393,10 +385,6 @@ LIBUS_SOCKET_DESCRIPTOR bsd_accept_socket(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd
393385
return bsd_set_nonblocking(apple_no_sigpipe(accepted_fd));
394386
}
395387

396-
int bsd_recv(LIBUS_SOCKET_DESCRIPTOR fd, void *buf, int length, int flags) {
397-
return recv(fd, buf, length, flags);
398-
}
399-
400388
int bsd_send(LIBUS_SOCKET_DESCRIPTOR fd, const char *buf, int length, int msg_more) {
401389

402390
// MSG_MORE (Linux), MSG_PARTIAL (Windows), TCP_NOPUSH (BSD)

src/context.c

Lines changed: 1 addition & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,10 @@
2020
#include <stdlib.h>
2121
#include <string.h>
2222

23-
int default_is_low_prio_handler(struct us_socket_t *s) {
24-
return 0;
25-
}
23+
int default_is_low_prio_handler(struct us_socket_t *s);
2624

2725
/* Shared with SSL */
2826

29-
unsigned short us_socket_context_timestamp(int ssl, struct us_socket_context_t *context) {
30-
return context->timestamp;
31-
}
32-
3327
void us_listen_socket_close(int ssl, struct us_listen_socket_t *ls) {
3428
/* us_listen_socket_t extends us_socket_t so we close in similar ways */
3529
if (!us_socket_is_closed(0, &ls->s)) {
@@ -128,10 +122,6 @@ void us_internal_socket_context_link_socket(struct us_socket_context_t *context,
128122
context->head_sockets = s;
129123
}
130124

131-
struct us_loop_t *us_socket_context_loop(int ssl, struct us_socket_context_t *context) {
132-
return context->loop;
133-
}
134-
135125
/* Not shared with SSL */
136126

137127
/* Lookup userdata by server name pattern */
@@ -198,53 +188,6 @@ void *us_socket_context_get_native_handle(int ssl, struct us_socket_context_t *c
198188
return 0;
199189
}
200190

201-
/* Options is currently only applicable for SSL - this will change with time (prefer_low_memory is one example) */
202-
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) {
203-
#ifndef LIBUS_NO_SSL
204-
if (ssl) {
205-
/* This function will call us, again, with SSL = false and a bigger ext_size */
206-
return (struct us_socket_context_t *) us_internal_create_ssl_socket_context(loop, context_ext_size, options);
207-
}
208-
#endif
209-
210-
/* This path is taken once either way - always BEFORE whatever SSL may do LATER.
211-
* context_ext_size will however be modified larger in case of SSL, to hold SSL extensions */
212-
213-
struct us_socket_context_t *context = malloc(sizeof(struct us_socket_context_t) + context_ext_size);
214-
context->loop = loop;
215-
context->head_sockets = 0;
216-
context->head_listen_sockets = 0;
217-
context->iterator = 0;
218-
context->next = 0;
219-
context->is_low_prio = default_is_low_prio_handler;
220-
221-
/* Begin at 0 */
222-
context->timestamp = 0;
223-
context->long_timestamp = 0;
224-
context->global_tick = 0;
225-
226-
us_internal_loop_link(loop, context);
227-
228-
/* If we are called from within SSL code, SSL code will make further changes to us */
229-
return context;
230-
}
231-
232-
void us_socket_context_free(int ssl, struct us_socket_context_t *context) {
233-
#ifndef LIBUS_NO_SSL
234-
if (ssl) {
235-
/* This function will call us again with SSL=false */
236-
us_internal_ssl_socket_context_free((struct us_internal_ssl_socket_context_t *) context);
237-
return;
238-
}
239-
#endif
240-
241-
/* This path is taken once either way - always AFTER whatever SSL may do BEFORE.
242-
* This is the opposite order compared to when creating the context - SSL code is cleaning up before non-SSL */
243-
244-
us_internal_loop_unlink(context->loop, context);
245-
free(context);
246-
}
247-
248191
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) {
249192
#ifndef LIBUS_NO_SSL
250193
if (ssl) {
@@ -412,94 +355,6 @@ struct us_socket_t *us_socket_context_adopt_socket(int ssl, struct us_socket_con
412355
return new_s;
413356
}
414357

415-
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)) {
416-
#ifndef LIBUS_NO_SSL
417-
if (ssl) {
418-
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);
419-
return;
420-
}
421-
#endif
422-
423-
context->on_open = on_open;
424-
}
425-
426-
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)) {
427-
#ifndef LIBUS_NO_SSL
428-
if (ssl) {
429-
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);
430-
return;
431-
}
432-
#endif
433-
434-
context->on_close = on_close;
435-
}
436-
437-
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)) {
438-
#ifndef LIBUS_NO_SSL
439-
if (ssl) {
440-
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);
441-
return;
442-
}
443-
#endif
444-
445-
context->on_data = on_data;
446-
}
447-
448-
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)) {
449-
#ifndef LIBUS_NO_SSL
450-
if (ssl) {
451-
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);
452-
return;
453-
}
454-
#endif
455-
456-
context->on_writable = on_writable;
457-
}
458-
459-
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 *)) {
460-
#ifndef LIBUS_NO_SSL
461-
if (ssl) {
462-
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);
463-
return;
464-
}
465-
#endif
466-
467-
context->on_socket_long_timeout = on_long_timeout;
468-
}
469-
470-
void us_socket_context_on_timeout(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_timeout)(struct us_socket_t *)) {
471-
#ifndef LIBUS_NO_SSL
472-
if (ssl) {
473-
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);
474-
return;
475-
}
476-
#endif
477-
478-
context->on_socket_timeout = on_timeout;
479-
}
480-
481-
void us_socket_context_on_end(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_end)(struct us_socket_t *)) {
482-
#ifndef LIBUS_NO_SSL
483-
if (ssl) {
484-
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);
485-
return;
486-
}
487-
#endif
488-
489-
context->on_end = on_end;
490-
}
491-
492-
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)) {
493-
#ifndef LIBUS_NO_SSL
494-
if (ssl) {
495-
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);
496-
return;
497-
}
498-
#endif
499-
500-
context->on_connect_error = on_connect_error;
501-
}
502-
503358
void *us_socket_context_ext(int ssl, struct us_socket_context_t *context) {
504359
#ifndef LIBUS_NO_SSL
505360
if (ssl) {

src/epoll_kqueue.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use super::*;
2+
3+
struct epoll_event {
4+
events: u32, /* Epoll events */
5+
data: u64 /* User data variable */
6+
}
7+
8+
struct kevent {
9+
ident: usize, /* identifier for this event */
10+
filter: i16, /* filter for event */
11+
flags: u16, /* action flags for kqueue */
12+
fflags: u32, /* filter flag value */
13+
data: i64, /* filter data value */
14+
udata: usize /* opaque user data identifier */
15+
}
16+
17+
18+
const LIBUS_SOCKET_READABLE: i32 = 1;
19+
const LIBUS_SOCKET_WRITABLE: i32 = 2;
20+
21+
#[repr(C)]
22+
pub struct us_loop_t {
23+
/* us_loop_t is always convertible to us_internal_loop_data_t */
24+
pub data: us_internal_loop_data_t,
25+
26+
/* Number of non-fallthrough polls in the loop */
27+
num_polls: i32,
28+
29+
/* Number of ready polls this iteration */
30+
num_ready_polls: i32,
31+
32+
/* Current index in list of ready polls */
33+
current_ready_poll: i32,
34+
35+
/* Loop's own file descriptor */
36+
fd: i32,
37+
38+
/* The list of ready polls */
39+
#[cfg(LIBUS_USE_EPOLL)]
40+
ready_polls: [epoll_event; 1024],
41+
#[cfg(not(LIBUS_USE_EPOLL))]
42+
ready_polls: [kevent; 1024]
43+
}
44+
45+
pub struct us_poll_t {
46+
data: u32
47+
// alignas(LIBUS_EXT_ALIGNMENT) struct {
48+
// signed int fd : 28; // we could have this unsigned if we wanted to, -1 should never be used
49+
// unsigned int poll_type : 4;
50+
// } state;
51+
}
52+
53+
/* Loop */
54+
#[no_mangle]
55+
pub unsafe extern "C" fn us_loop_free(_loop: *mut us_loop_t) {
56+
us_internal_loop_data_free(_loop/*(*_loop)*//*.data*/);
57+
close((*_loop).fd);
58+
free(_loop as *mut us_socket_context_t);
59+
}
60+
61+
unsafe fn k() {
62+
bsd_socket_flush(0);
63+
}

src/eventing/epoll_kqueue.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,6 @@
3232
#define SET_READY_POLL(loop, index, poll) loop->ready_polls[index].udata = poll
3333
#endif
3434

35-
/* Loop */
36-
void us_loop_free(struct us_loop_t *loop) {
37-
us_internal_loop_data_free(loop);
38-
close(loop->fd);
39-
free(loop);
40-
}
41-
4235
/* Poll */
4336
struct us_poll_t *us_create_poll(struct us_loop_t *loop, int fallthrough, unsigned int ext_size) {
4437
if (!fallthrough) {

0 commit comments

Comments
 (0)