aboutsummaryrefslogtreecommitdiff
path: root/client/libacron/net.c
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2022-07-23 11:03:20 -0700
committerTrumeet <yuuta@yuuta.moe>2022-07-23 11:03:20 -0700
commit6c49e2e93b23defd51d4b342baad5a9c3f843ea1 (patch)
treeccf1c90934571fe9472c85ea86ee1c5112ce3e65 /client/libacron/net.c
parent4337729c2fa77871e3b10cbe329f286c01ddc01f (diff)
downloadacron-6c49e2e93b23defd51d4b342baad5a9c3f843ea1.tar
acron-6c49e2e93b23defd51d4b342baad5a9c3f843ea1.tar.gz
acron-6c49e2e93b23defd51d4b342baad5a9c3f843ea1.tar.bz2
acron-6c49e2e93b23defd51d4b342baad5a9c3f843ea1.zip
feat(libacron/acronc): delegate socket IO to the client
API:CHANGE Signed-off-by: Trumeet <yuuta@yuuta.moe>
Diffstat (limited to 'client/libacron/net.c')
-rw-r--r--client/libacron/net.c210
1 files changed, 51 insertions, 159 deletions
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 <stdio.h>
#include <string.h>
-#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
-#ifdef WIN32
-#include <windows.h> /* For DWORD */
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#define errno_sock WSAGetLastError()
-#else
-#define errno_sock errno
-#include <sys/socket.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <sys/time.h>
-#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;
+}