add connection read/write methods
This commit is contained in:
parent
cd3ce5452d
commit
665710cf96
|
@ -9,7 +9,7 @@ int main(int argc, char **argv) {
|
||||||
tls_init();
|
tls_init();
|
||||||
config = tls_config_new();
|
config = tls_config_new();
|
||||||
connection_init(EV_DEFAULT_ & connection, config);
|
connection_init(EV_DEFAULT_ & connection, config);
|
||||||
ev_run(EV_DEFAULT_UC_ 0);
|
|
||||||
tls_config_free(config);
|
tls_config_free(config);
|
||||||
|
ev_run(EV_DEFAULT_UC_ 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <assert.h>
|
||||||
#include <network.h>
|
#include <network.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -6,21 +7,104 @@
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
|
|
||||||
|
typedef void (*ConnectionCallback)(EV_P_ Connection *);
|
||||||
|
|
||||||
struct Connection {
|
struct Connection {
|
||||||
ev_io watcher;
|
ev_io watcher;
|
||||||
struct tls *ctx;
|
struct tls *ctx;
|
||||||
|
ConnectionCallback success_cb;
|
||||||
|
ConnectionCallback failure_cb;
|
||||||
|
Buffer read_buf;
|
||||||
|
Buffer write_buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Buffer {
|
||||||
|
size_t size;
|
||||||
|
char data[4096];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void connection_init(EV_P_ Connection *connection, struct tls_config *config) {
|
void connection_init(EV_P_ Connection *connection, struct tls_config *config) {
|
||||||
ev_io_init(&connection->watcher, connection_cb, STDIN_FILENO, EV_READ);
|
ev_io_init(&connection->watcher, NULL, STDIN_FILENO, 0);
|
||||||
ev_io_start(EV_A_ & connection->watcher);
|
|
||||||
connection->ctx = tls_client();
|
connection->ctx = tls_client();
|
||||||
tls_configure(connection->ctx, config);
|
tls_configure(connection->ctx, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void connection_cb(EV_P_ ev_io *w, int revents) {
|
#define connection_set_failure_cb(connection, callback) \
|
||||||
ev_io_stop(EV_A_ w);
|
do { \
|
||||||
ev_break(EV_A_ EVBREAK_ALL);
|
(connection)->failure_cb = callback; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define connection_set_cb(connection, callback) \
|
||||||
|
do { \
|
||||||
|
(connection)->success_cb = callback; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define connection_read_buf(connection) &((connection)->read_buf)
|
||||||
|
#define connection_write_buf(connection) &((connection)->write_buf)
|
||||||
|
|
||||||
|
void connection_read_some(EV_P_ Connection *connection) {
|
||||||
|
assert(connection->success_cb && connection->failure_cb);
|
||||||
|
ev_set_cb(&connection->watcher, connection_read_some_cb);
|
||||||
|
ev_invoke(EV_A_ & connection->watcher, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void connection_read_some_cb(EV_P_ ev_io *watcher, int revents) {
|
||||||
|
Connection *connection = (Connection *)watcher;
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
(void)revents;
|
||||||
|
ev_io_stop(EV_A_ watcher);
|
||||||
|
n = tls_read(connection->ctx,
|
||||||
|
&connection->read_buf.data[connection->read_buf.size],
|
||||||
|
sizeof(connection->read_buf.data) - connection->read_buf.size);
|
||||||
|
if (n == TLS_WANT_POLLIN) {
|
||||||
|
ev_io_modify(watcher, EV_READ);
|
||||||
|
ev_io_start(EV_A_ watcher);
|
||||||
|
} else if (n == TLS_WANT_POLLOUT) {
|
||||||
|
ev_io_modify(watcher, EV_WRITE);
|
||||||
|
ev_io_start(EV_A_ watcher);
|
||||||
|
} else if (n == -1) {
|
||||||
|
connection->failure_cb(EV_A_ connection);
|
||||||
|
} else {
|
||||||
|
connection->read_buf.size += n;
|
||||||
|
connection->success_cb(EV_A_ connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection_write_some(EV_P_ Connection *connection) {
|
||||||
|
assert(connection->success_cb && connection->failure_cb);
|
||||||
|
ev_set_cb(&connection->watcher, connection_write_some_cb);
|
||||||
|
ev_invoke(EV_A_ & connection->watcher, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void connection_write_some_cb(EV_P_ ev_io *watcher, int revents) {
|
||||||
|
Connection *connection = (Connection *)watcher;
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
(void)revents;
|
||||||
|
ev_io_stop(EV_A_ watcher);
|
||||||
|
n = tls_write(connection->ctx, connection->write_buf.data,
|
||||||
|
connection->write_buf.size);
|
||||||
|
if (n == TLS_WANT_POLLIN) {
|
||||||
|
ev_io_modify(watcher, EV_READ);
|
||||||
|
ev_io_start(EV_A_ watcher);
|
||||||
|
} else if (n == TLS_WANT_POLLOUT) {
|
||||||
|
ev_io_modify(watcher, EV_WRITE);
|
||||||
|
ev_io_start(EV_A_ watcher);
|
||||||
|
} else if (n == -1) {
|
||||||
|
connection->failure_cb(EV_A_ connection);
|
||||||
|
} else {
|
||||||
|
connection->write_buf.size -= n;
|
||||||
|
memmove(connection->write_buf.data, &connection->write_buf.data[n],
|
||||||
|
connection->write_buf.size);
|
||||||
|
connection->success_cb(EV_A_ connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection_stop(EV_P_ Connection *connection) {
|
||||||
|
ev_io_stop(EV_A_ & connection->watcher);
|
||||||
|
close(connection->watcher.fd);
|
||||||
|
tls_free(connection->ctx);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue