mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-06 10:22:26 +00:00
177 lines
4.3 KiB
C
177 lines
4.3 KiB
C
//%LICENSE////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2015 Devchandra M. Leishangthem (dlmeetei at gmail dot com)
|
|
//
|
|
// Distributed under the MIT License (See accompanying file LICENSE)
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//%///////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "uv_tls.h"
|
|
#include <assert.h>
|
|
|
|
static void alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf)
|
|
{
|
|
buf->base = (char*)malloc(size);
|
|
memset(buf->base, 0, size);
|
|
buf->len = size;
|
|
assert(buf->base != NULL && "Memory allocation failed");
|
|
}
|
|
|
|
int uv_tls_writer(evt_tls_t *t, void *bfr, int sz) {
|
|
int rv = 0;
|
|
uv_buf_t b;
|
|
b.base = bfr;
|
|
b.len = sz;
|
|
uv_tls_t *uvt = t->data;
|
|
if(uv_is_writable((uv_stream_t*)&(uvt->skt)) ) {
|
|
rv = uv_try_write((uv_stream_t*)&(uvt->skt), &b, 1);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
int uv_tls_init(uv_loop_t *loop, evt_ctx_t *ctx, uv_tls_t *endpt)
|
|
{
|
|
int r = 0;
|
|
memset( endpt, 0, sizeof *endpt);
|
|
|
|
r = uv_tcp_init(loop, &(endpt->skt));
|
|
|
|
evt_tls_t *t = evt_ctx_get_tls(ctx);
|
|
assert( t != NULL );
|
|
|
|
t->data = endpt;
|
|
|
|
endpt->tls = t;
|
|
endpt->tls_rd_cb = NULL;
|
|
endpt->tls_cls_cb = NULL;
|
|
endpt->tls_hsk_cb = NULL;
|
|
endpt->tls_wr_cb = NULL;
|
|
return r;
|
|
}
|
|
|
|
void on_tcp_read(uv_stream_t *stream, ssize_t nrd, const uv_buf_t *data)
|
|
{
|
|
uv_tls_t *parent = CONTAINER_OF(stream, uv_tls_t, skt);
|
|
assert( parent != NULL);
|
|
if ( nrd <= 0 ) {
|
|
if( nrd == UV_EOF) {
|
|
uv_tls_close((uv_handle_t*)stream, (uv_close_cb)free);
|
|
}
|
|
free(data->base);
|
|
return;
|
|
}
|
|
|
|
static int is_tls = 0;
|
|
static int is_first = 1;
|
|
if (is_first) {
|
|
if (is_tls_stream(data->base, nrd)) {
|
|
evt_tls_feed_data(parent->tls, data->base, nrd);
|
|
is_tls = 1;
|
|
}
|
|
is_first = 0;
|
|
}
|
|
else {
|
|
if(is_tls) {
|
|
evt_tls_feed_data(parent->tls, data->base, nrd);
|
|
}
|
|
}
|
|
free(data->base);
|
|
}
|
|
|
|
static void on_hd_complete( evt_tls_t *t, int status)
|
|
{
|
|
uv_tls_t *ut = (uv_tls_t*)t->data;
|
|
assert( ut != NULL && ut->tls_hsk_cb != NULL);
|
|
ut->tls_hsk_cb(ut, status -1);
|
|
}
|
|
|
|
|
|
int uv_tls_accept(uv_tls_t *t, uv_handshake_cb cb)
|
|
{
|
|
int rv = 0;
|
|
assert( t != NULL);
|
|
t->tls_hsk_cb = cb;
|
|
evt_tls_t *tls = t->tls;
|
|
rv = evt_tls_accept(tls, on_hd_complete);
|
|
uv_read_start((uv_stream_t*)&(t->skt), alloc_cb, on_tcp_read);
|
|
return rv;
|
|
}
|
|
|
|
static void evt_on_rd(evt_tls_t *t, char *bfr, int sz)
|
|
{
|
|
uv_buf_t data;
|
|
uv_tls_t *tls = (uv_tls_t*)t->data;
|
|
|
|
data.base = bfr;
|
|
data.len = sz;
|
|
|
|
assert(tls->tls_rd_cb != NULL);
|
|
tls->tls_rd_cb((uv_stream_t*)tls, sz, &data);
|
|
}
|
|
|
|
void on_close(evt_tls_t *tls, int status)
|
|
{
|
|
assert(1 == status);
|
|
uv_tls_t *ut = (uv_tls_t*)tls->data;
|
|
assert( ut->tls_cls_cb != NULL);
|
|
|
|
evt_tls_free(tls);
|
|
if ( !uv_is_closing((uv_handle_t*)&(ut->skt)))
|
|
uv_close( (uv_handle_t*)&(ut->skt), ut->tls_cls_cb);
|
|
}
|
|
|
|
int uv_tls_close(uv_handle_t *strm, uv_close_cb cb)
|
|
{
|
|
uv_tls_t *t = (uv_tls_t*)strm;
|
|
t->tls_cls_cb = cb;
|
|
|
|
return evt_tls_close(t->tls, on_close);
|
|
}
|
|
|
|
//uv_alloc_cb is unused. This is here to mimick API similarity with libuv
|
|
// XXX remove?
|
|
int uv_tls_read(uv_stream_t *tls, uv_alloc_cb alloc_cb, uv_read_cb cb)
|
|
{
|
|
uv_tls_t *ptr = (uv_tls_t*)tls;
|
|
ptr->tls_rd_cb = cb;
|
|
return evt_tls_read(ptr->tls, evt_on_rd);
|
|
}
|
|
|
|
static void on_hshake(evt_tls_t *etls, int status)
|
|
{
|
|
assert(etls != NULL);
|
|
uv_tls_t *ut = (uv_tls_t*)etls->data;
|
|
assert(ut != NULL && ut->tls_hsk_cb != NULL);
|
|
ut->tls_hsk_cb(ut, status - 1);
|
|
}
|
|
|
|
int uv_tls_connect(uv_tls_t *t, uv_handshake_cb cb)
|
|
{
|
|
assert( t != NULL);
|
|
t->tls_hsk_cb = cb;
|
|
evt_tls_t *evt = t->tls;
|
|
assert( evt != NULL);
|
|
|
|
evt_tls_connect(evt, on_hshake);
|
|
return uv_read_start((uv_stream_t*)&(t->skt), alloc_cb, on_tcp_read);
|
|
}
|
|
|
|
void on_evt_write(evt_tls_t *tls, int status) {
|
|
assert( tls != NULL);
|
|
uv_tls_t *ut = (uv_tls_t*)tls->data;
|
|
assert( ut != NULL && ut->tls_wr_cb != NULL);
|
|
ut->tls_wr_cb(ut, status);
|
|
}
|
|
|
|
int uv_tls_write(uv_tls_t *stream, uv_buf_t *buf, uv_tls_write_cb cb)
|
|
{
|
|
assert( stream != NULL);
|
|
stream->tls_wr_cb = cb;
|
|
evt_tls_t *evt = stream->tls;
|
|
assert( evt != NULL);
|
|
|
|
return evt_tls_write(evt, buf->base, buf->len, on_evt_write);
|
|
}
|