#include "tcp_internal.h"
#include "sock_internal.h"
#include <unistd.h>
/*
* Our transport_type
*/
const struct transport_type tcp_transport_type = {
.base_type = {
.parent = &transport_fd_type.base_type,
},
.methods = {
.read = transport_fd__read,
.write = transport_fd__write,
.events = transport_fd__events,
.deinit = transport_fd__deinit,
},
};
void tcp_transport_init (struct tcp_transport *trans, evutil_socket_t sock)
{
struct event_base *ev_base = _sock_stream_ctx.ev_base;
transport_fd_init(&trans->base_fd, ev_base, sock);
}
err_t tcp_transport_create (struct tcp_transport **trans_ptr, const struct transport_info *info, evutil_socket_t sock, error_t *err)
{
struct tcp_transport *trans;
// alloc
if ((trans = calloc(1, sizeof(*trans))) == NULL)
JUMP_SET_ERROR(err, ERR_MEM);
// init transport
transport_init(&trans->base_fd.base, &tcp_transport_type, info);
// init ourselves
tcp_transport_init(trans, sock);
// setup the socket?
if (sock >= 0) {
// make it non-blocking
if ((ERROR_CODE(err) = transport_fd_nonblock(&trans->base_fd, true)))
goto error;
}
// ok
*trans_ptr = trans;
return SUCCESS;
error:
// cleanup
if (trans)
tcp_transport_deinit(trans);
else
EVUTIL_CLOSESOCKET(sock);
return ERROR_CODE(err);
}
err_t tcp_transport_connected (struct tcp_transport *trans, error_t *err)
{
// set up for default transport event-based operation
if ((ERROR_CODE(err) = transport_fd_defaults(&trans->base_fd)))
return ERROR_CODE(err);
// ok
transport_connected(&trans->base_fd.base, NULL, false);
return SUCCESS;
}
void tcp_transport_deinit (struct tcp_transport *trans)
{
transport_fd_deinit(&trans->base_fd);
}
void tcp_transport_destroy (struct tcp_transport *trans)
{
tcp_transport_deinit(trans);
free(trans);
}