From 6c49e2e93b23defd51d4b342baad5a9c3f843ea1 Mon Sep 17 00:00:00 2001 From: Trumeet Date: Sat, 23 Jul 2022 11:03:20 -0700 Subject: feat(libacron/acronc): delegate socket IO to the client API:CHANGE Signed-off-by: Trumeet --- client/libacron/net.c | 210 ++++++++++++-------------------------------------- 1 file changed, 51 insertions(+), 159 deletions(-) (limited to 'client/libacron/net.c') diff --git a/client/libacron/net.c b/client/libacron/net.c index bbfb465..1af752c 100644 --- a/client/libacron/net.c +++ b/client/libacron/net.c @@ -2,7 +2,6 @@ * Created by yuuta on 7/13/22. */ -#include "win32.h" #include "config.h" #include "net.h" #include "connection.h" @@ -15,24 +14,10 @@ #include #include -#include #include #include #include -#ifdef WIN32 -#include /* For DWORD */ -#include -#include -#define errno_sock WSAGetLastError() -#else -#define errno_sock errno -#include -#include -#include -#include -#endif - static void conn_free(struct ac_connection *conn) { if (conn->url) free(conn->url); if (conn->parameters.id) free(conn->parameters.id); @@ -41,33 +26,12 @@ static void conn_free(struct ac_connection *conn) { free(conn); } -static void on_open_handler(struct wic_inst *inst) { - struct ac_connection *conn = wic_get_app(inst); - conn->established = true; -} - static void on_send_handler(struct wic_inst *inst, const void *data, size_t size, enum wic_buffer type) { struct ac_connection *conn = wic_get_app(inst); - size_t pos; - const uint8_t *ptr = data; - int retval; - - for (pos = 0U; pos < size; pos += retval) { - size_t n = size - pos; - LOGDV("write(%d, %p[%u, %u])", conn->fd, data, pos, n); - retval = (int) send(conn->fd, &ptr[pos], (int) n, 0); - if (retval <= 0) { - /* There's no way to abort the process. */ - int e = errno_sock; - LOGEV("Cannot write to socket: %s (%d).", - strerror2(errno), - e); - break; - } - } + conn->parameters.on_send(conn->parameters.sock, data, size); free((void *) data); } @@ -128,7 +92,9 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) { if (!parameters.id || !parameters.host || - !parameters.token) { + !parameters.token || + !parameters.sock || + !parameters.on_send) { LOGE("Required parameters are missing."); return AC_E_INVALID_REQUEST; } @@ -140,6 +106,9 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) { } /* Do not use memcpy() here because we want to keep track of copied and not-copied strings. */ conn->parameters.port = parameters.port; + conn->parameters.sock = parameters.sock; + conn->parameters.version = parameters.version; + conn->parameters.on_send = parameters.on_send; if ((r = strdup2(parameters.token, &conn->parameters.token)) || (r = strdup2(parameters.host, &conn->parameters.host)) || (r = strdup2(parameters.id, &conn->parameters.id))) { @@ -183,7 +152,6 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) { arg.rx_max = sizeof(rx); arg.on_send = on_send_handler; - arg.on_open = on_open_handler; arg.on_message = on_message_handler; arg.on_buffer = on_buffer_handler; @@ -197,82 +165,12 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) { return AC_E_INTERNAL; } - struct addrinfo *res; - char service[6]; - - const enum wic_schema schema = wic_get_url_schema(inst); - const uint16_t port = wic_get_url_port(inst); - snprintf(service, 6, "%u", port); - const char *host = wic_get_url_hostname(inst); - - switch (schema) { - case WIC_SCHEMA_WS: - break; - case WIC_SCHEMA_WSS: - LOGE("WSS is not supported yet."); - conn_free(conn); - return AC_E_INVALID_REQUEST; - default: - LOGE("Unsupported protocol. The URL must be ws://"); - conn_free(conn); - return AC_E_INVALID_REQUEST; - } - - if ((r = getaddrinfo(host, service, NULL, &res))) { - /* gai_strerror() seems to cause an linkage error. */ -#ifdef WIN32 - LOGEV("Resolve host: %d.", r); -#else - LOGEV("Resolve host: %s.", gai_strerror(r)); -#endif - r = AC_E_NET; - conn_free(conn); - return r; - } - - SOCKET fd; - if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) <= 0) { - const int e = errno_sock; - LOGEV("Cannot create socket: %s (%d).", - strerror2(e), - e); - freeaddrinfo(res); - conn_free(conn); - return AC_E_NET; - } - if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) { - const int e = errno_sock; - LOGEV("Cannot connect to socket: %s (%d).", - strerror2(e), - e); - closesocket(fd); - freeaddrinfo(res); - conn_free(conn); - return AC_E_NET; - } - freeaddrinfo(res); - - conn->fd = fd; if (wic_start(inst) != WIC_STATUS_SUCCESS) { LOGE("Cannot start the WIC client."); - closesocket(fd); conn_free(conn); return AC_E_NET; } - /* Wait until established (ready to send). */ - while (!conn->established) { - ac_obj_t *obj = NULL; - r = ac_receive(conn, &obj, 0); - if (obj) { - LOGW("Received an object before connection is established. Dropping."); - ac_object_free(obj); - } - if (r) { - ac_disconnect(conn); - return r; - } - } *out = conn; return AC_E_OK; } @@ -280,70 +178,27 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) { int ac_disconnect(void *connection) { AC_CHECK_INIT; struct ac_connection *conn = connection; - if (!conn->fd) { - LOGE("Trying to disconnect an already disconnected connection."); - return AC_E_INVALID_REQUEST; - } LOGD("Disconnecting..."); wic_close(&conn->inst); - closesocket(conn->fd); conn_free(conn); return AC_E_OK; } -int ac_receive(void *connection, ac_obj_t **response, long timeout) { +int ac_receive(void *connection, + const void *buffer, + const size_t len, + ac_obj_t **response) { AC_CHECK_INIT; struct ac_connection *conn = connection; struct wic_inst *inst = &conn->inst; - static uint8_t buffer[1000U]; - int bytes; + const uint8_t *ptr = buffer; size_t retval, pos; -#ifdef WIN32 - DWORD to = timeout * 1000; - if (setsockopt(conn->fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&to, sizeof to)) { -#else - struct timeval tv; - tv.tv_sec = timeout; - tv.tv_usec = 0; - if (setsockopt(conn->fd, SOL_SOCKET, SO_RCVTIMEO, (const char *) &tv, sizeof tv)) { -#endif - const int e = errno_sock; - LOGEV("Failed to call setsockopt(3): %s (%d).", - strerror2(e), - e); - return AC_E_INTERNAL; - } - - if ((bytes = (int) recv(conn->fd, buffer, sizeof(buffer), 0)) <= 0) { - LOGDV("recv(%d) = %d", conn->fd, bytes); - if (bytes < 0) { - const int e = errno_sock; -#ifdef WIN32 - if (e == WSAETIMEDOUT) { -#else - if (e == EAGAIN) { -#endif - /* Timeout */ - *response = NULL; - return AC_E_OK; - } - LOGEV("Failed to receive from socket : %s (%d).", - strerror2(e), - e); - } else { - LOGI("Peer abnormally shutdown."); - } - wic_close_with_reason(inst, WIC_CLOSE_ABNORMAL_2, NULL, 0); - return AC_E_NET; - } - LOGDV("recv(%d) = %d", conn->fd, bytes); - /* In case the deserializer does not run at all. */ memset(&conn->result, 0, sizeof(struct ac_result)); - for (pos = 0U; pos < bytes; pos += retval) { - retval = wic_parse(inst, &buffer[pos], bytes - pos); + for (pos = 0U; pos < len; pos += retval) { + retval = wic_parse(inst, &ptr[pos], len - pos); if (wic_get_state(inst) == WIC_STATE_CLOSED) { LOGE("Connection closed."); return AC_E_NET; @@ -390,6 +245,17 @@ int ac_request(void *connection, const ac_request_t *request) { LOGE("Cannot serialize JSON."); return AC_E_INTERNAL; } + /** + * Access: + * * inst->role (ro, safe) + * * inst->state (rw, unsafe) + * * inst->utf8_tx (rw, safe) + * * inst->frag (rw, safe) + * * inst->on_buffer (ro, unsafe) + * * inst->on_sand (ro, unsafe) + * * conn->fd (ro, unsafe) + * * write(ro, unsafe) + */ if (wic_send_text(inst, true, str, len) != WIC_STATUS_SUCCESS) { LOGE("Cannot send."); json_object_put(obj); @@ -398,3 +264,29 @@ int ac_request(void *connection, const ac_request_t *request) { json_object_put(obj); return AC_E_OK; } + +int ac_get_state(void *connection, enum ac_connection_state *out) { + AC_CHECK_INIT; + struct ac_connection *conn = connection; + switch (wic_get_state(&conn->inst)) { + case WIC_STATE_CLOSED: { + *out = AC_STATE_CLOSED; + break; + } + case WIC_STATE_PARSE_HANDSHAKE: + case WIC_STATE_INIT: { + *out = AC_STATE_INIT; + break; + } + case WIC_STATE_OPEN: + case WIC_STATE_READY: { + *out = AC_STATE_READY; + break; + } + default: { + *out = AC_STATE_INIT; + break; + } + } + return AC_E_OK; +} -- cgit v1.2.3