summaryrefslogtreecommitdiff
path: root/src/socket
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2023-11-06 10:33:45 -0500
committerAndrew Opalach <andrew@akon.city> 2023-11-06 10:33:45 -0500
commit1517f2874ab44fcf210c14e9fdd3f9c1bfd6ba76 (patch)
tree641dd55f6677bea75c691b6010c0d7dd2a5f37e8 /src/socket
parenta723efcc67b6c14ff0dd1efd1ba88596e959daaa (diff)
downloadlibnaunet-1517f2874ab44fcf210c14e9fdd3f9c1bfd6ba76.tar.gz
libnaunet-1517f2874ab44fcf210c14e9fdd3f9c1bfd6ba76.tar.bz2
libnaunet-1517f2874ab44fcf210c14e9fdd3f9c1bfd6ba76.zip
Update
- Refactor curl support, add curl websockets - Remove aki_socket config structure - Add the ability to change aki_timer repeat - Various fixes Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/socket')
-rw-r--r--src/socket/socket.h22
-rw-r--r--src/socket/socket_linux.c181
-rw-r--r--src/socket/socket_windows.c28
3 files changed, 105 insertions, 126 deletions
diff --git a/src/socket/socket.h b/src/socket/socket.h
index ea307e7..4971c1c 100644
--- a/src/socket/socket.h
+++ b/src/socket/socket.h
@@ -21,10 +21,6 @@ enum {
struct aki_socket {
u8 type;
- struct {
- bool blocking;
- bool no_delay;
- } config;
#ifndef _WIN32
s32 sock;
struct sockaddr_in addr_in;
@@ -37,20 +33,25 @@ struct aki_socket {
#ifndef _WIN32
#define aki_read read
-#else
-#define aki_read _read
-#endif
-
-#ifndef _WIN32
#define aki_write write
+#define aki_htons htons
+#define aki_htonl htonl
+#define aki_ntohs ntohs
#else
+#define aki_read _read
#define aki_write _write
+#define aki_htons(...) 0
+#define aki_htonl(...) 0
+#define aki_ntohs(...) 0
#endif
bool aki_socket_init(struct aki_socket *s);
void aki_socket_set_blocking(struct aki_socket *s, bool blocking);
-void aki_socket_set_no_delay(struct aki_socket *s, bool no_delay);
+void aki_socket_set_no_delay(struct aki_socket *s, s32 no_delay);
+
+void aki_socket_set_send_buf(struct aki_socket *s, u32 sndbuf);
+u32 aki_socket_get_send_buf(struct aki_socket *s);
bool aki_socket_listen(struct aki_socket *s, str *addr, s32 port);
bool aki_socket_accept(struct aki_socket *s, struct aki_socket *c);
@@ -61,6 +62,7 @@ s32 aki_socket_get_fd(struct aki_socket *s);
ssize_t aki_socket_read(struct aki_socket *s, void *buf, size_t size);
ssize_t aki_socket_write(struct aki_socket *s, void *buf, size_t size);
ssize_t aki_socket_sendto(struct aki_socket *s, void *buf, size_t size);
+ssize_t aki_socket_recvfrom(struct aki_socket *s, void *buf, size_t size);
void aki_socket_shutdown(struct aki_socket *s);
void aki_socket_close(struct aki_socket *s);
diff --git a/src/socket/socket_linux.c b/src/socket/socket_linux.c
index b466dea..7bc9ea9 100644
--- a/src/socket/socket_linux.c
+++ b/src/socket/socket_linux.c
@@ -9,48 +9,6 @@
#include "socket.h"
-static void socket_set_blocking(struct aki_socket *s, bool blocking)
-{
- s32 flags = fcntl(s->sock, F_GETFL, 0);
- al_assert(flags != -1);
- flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
- s32 ret = fcntl(s->sock, F_SETFL, flags);
- al_assert(ret == 0);
-}
-
-static void socket_set_no_delay(struct aki_socket *s, s32 no_delay)
-{
- if (s->type == AKI_SOCKET_TCP) {
- setsockopt(s->sock, IPPROTO_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay));
- }
-}
-
-static void socket_set_send_buf(struct aki_socket *s, u32 sndbuf)
-{
- u32 send_queue_size = sndbuf;
- setsockopt(s->sock, SOL_SOCKET, SO_SNDBUF, &send_queue_size, sizeof(send_queue_size));
-
- socklen_t optlen = sizeof(send_queue_size);
- getsockopt(s->sock, SOL_SOCKET, SO_SNDBUF, &send_queue_size, &optlen);
-
- if (send_queue_size != sndbuf * 2) {
- al_log_warn("socket", "Failed to set SO_SNDBUF.");
- }
-}
-
-static void socket_set_recv_buf(struct aki_socket *s, u32 rcvbuf)
-{
- u32 receive_queue_size = rcvbuf;
- setsockopt(s->sock, SOL_SOCKET, SO_RCVBUF, &receive_queue_size, sizeof(receive_queue_size));
-
- socklen_t optlen = sizeof(receive_queue_size);
- getsockopt(s->sock, SOL_SOCKET, SO_RCVBUF, &receive_queue_size, &optlen);
-
- if (receive_queue_size != rcvbuf * 2) {
- al_log_warn("socket", "Failed to set SO_RCVBUF.");
- }
-}
-
bool aki_socket_init(struct aki_socket *s)
{
switch (s->type) {
@@ -70,63 +28,52 @@ bool aki_socket_init(struct aki_socket *s)
return false;
}
- aki_socket_set_blocking(s, s->config.blocking);
- aki_socket_set_no_delay(s, s->config.no_delay);
-
return true;
}
void aki_socket_set_blocking(struct aki_socket *s, bool blocking)
{
- s->config.blocking = blocking;
- socket_set_blocking(s, blocking);
+ s32 flags = fcntl(s->sock, F_GETFL, 0);
+ al_assert(flags != -1);
+ flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
+ s32 ret = fcntl(s->sock, F_SETFL, flags);
+ al_assert(ret == 0);
}
-void aki_socket_set_no_delay(struct aki_socket *s, bool no_delay)
+void aki_socket_set_no_delay(struct aki_socket *s, s32 no_delay)
{
- s->config.no_delay = no_delay;
- socket_set_no_delay(s, no_delay);
+ if (s->type != AKI_SOCKET_TCP) return;
+ setsockopt(s->sock, IPPROTO_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay));
}
-bool aki_socket_accept(struct aki_socket *s, struct aki_socket *c)
+u32 aki_socket_get_send_buf(struct aki_socket *s)
{
- c->type = s->type;
-
- struct sockaddr_storage addr;
- socklen_t len = sizeof(addr);
- if((c->sock = accept(s->sock, (struct sockaddr *)&addr, &len)) == -1) {
- return false;
- }
+ u32 send_queue_size;
+ socklen_t optlen = sizeof(send_queue_size);
+ getsockopt(s->sock, SOL_SOCKET, SO_SNDBUF, &send_queue_size, &optlen);
+ return send_queue_size / 2;
+}
- aki_socket_set_blocking(c, c->config.blocking);
- aki_socket_set_no_delay(c, c->config.no_delay);
+void aki_socket_set_send_buf(struct aki_socket *s, u32 sndbuf)
+{
+ u32 send_queue_size = sndbuf;
+ setsockopt(s->sock, SOL_SOCKET, SO_SNDBUF, &send_queue_size, sizeof(send_queue_size));
+ al_assert(aki_socket_get_send_buf(s) == send_queue_size);
+}
- switch (s->type) {
- case AKI_SOCKET_TCP: {
- s32 port = 0;
- char ipstr[INET6_ADDRSTRLEN] = {0};
- if (addr.ss_family == AF_INET) {
- struct sockaddr_in *s = (struct sockaddr_in *)&addr;
- port = ntohs(s->sin_port);
- inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof(ipstr));
- } else if (addr.ss_family == AF_INET6) {
- struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
- port = ntohs(s->sin6_port);
- inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof(ipstr));
- }
- al_log_info("socket", "Connection from %s:%d.", ipstr, port);
- break;
- }
- case AKI_SOCKET_UNIX: {
- al_log_info("socket", "Connection from a UNIX socket.");
- break;
- }
- case AKI_SOCKET_UDP: {
- al_assert(false);
- }
- }
+u32 aki_socket_get_recv_buf(struct aki_socket *s)
+{
+ u32 receive_queue_size;
+ socklen_t optlen = sizeof(receive_queue_size);
+ getsockopt(s->sock, SOL_SOCKET, SO_RCVBUF, &receive_queue_size, &optlen);
+ return receive_queue_size / 2;
+}
- return true;
+void aki_socket_set_recv_buf(struct aki_socket *s, u32 rcvbuf)
+{
+ u32 receive_queue_size = rcvbuf;
+ setsockopt(s->sock, SOL_SOCKET, SO_RCVBUF, &receive_queue_size, sizeof(receive_queue_size));
+ al_assert(aki_socket_get_recv_buf(s) == receive_queue_size);
}
bool aki_socket_listen(struct aki_socket *s, str *addr, s32 port)
@@ -154,10 +101,9 @@ bool aki_socket_listen(struct aki_socket *s, str *addr, s32 port)
addrlen = sizeof(s->addr_un);
break;
}
- case AKI_SOCKET_UDP: {
+ case AKI_SOCKET_UDP:
al_assert(false);
}
- }
if (bind(s->sock, saddr, addrlen) < 0) {
al_log_error("socket", "Failed to bind (%.*s:%d).", AL_STR_PRINTF(addr), port);
@@ -176,10 +122,47 @@ bool aki_socket_listen(struct aki_socket *s, str *addr, s32 port)
return true;
}
-bool aki_socket_connect(struct aki_socket *s, str *addr, s32 port)
+bool aki_socket_accept(struct aki_socket *s, struct aki_socket *c)
{
+ c->type = s->type;
+
+ struct sockaddr_storage addr;
+ socklen_t len = sizeof(addr);
+ if ((c->sock = accept(s->sock, (struct sockaddr *)&addr, &len)) == -1) {
+ return false;
+ }
+
switch (s->type) {
case AKI_SOCKET_TCP: {
+ s32 port = 0;
+ char ipstr[INET6_ADDRSTRLEN] = {0};
+ if (addr.ss_family == AF_INET) {
+ struct sockaddr_in *s = (struct sockaddr_in *)&addr;
+ port = ntohs(s->sin_port);
+ inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof(ipstr));
+ } else if (addr.ss_family == AF_INET6) {
+ struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
+ port = ntohs(s->sin6_port);
+ inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof(ipstr));
+ }
+ al_log_info("socket", "Connection from %s:%d.", ipstr, port);
+ break;
+ }
+ case AKI_SOCKET_UNIX:
+ al_log_info("socket", "Connection from a UNIX socket.");
+ break;
+ case AKI_SOCKET_UDP:
+ al_assert(false);
+ }
+
+ return true;
+}
+
+bool aki_socket_connect(struct aki_socket *s, str *addr, s32 port)
+{
+ switch (s->type) {
+ case AKI_SOCKET_TCP:
+ case AKI_SOCKET_UDP: {
char *c_str = al_str_to_c_str(addr);
struct hostent *hptr = gethostbyname(c_str);
al_free(c_str);
@@ -198,13 +181,20 @@ bool aki_socket_connect(struct aki_socket *s, str *addr, s32 port)
s->addr_in.sin_addr.s_addr = ((struct in_addr *)hptr->h_addr_list[0])->s_addr;
s->addr_in.sin_port = htons(port);
- s32 ret = connect(s->sock, (struct sockaddr *)&s->addr_in, sizeof(s->addr_in));
+ break;
+ }
+ default:
+ break;
+ }
+ switch (s->type) {
+ case AKI_SOCKET_TCP:
+ case AKI_SOCKET_UDP: {
+ s32 ret = connect(s->sock, (struct sockaddr *)&s->addr_in, sizeof(s->addr_in));
if (ret != 0 && errno != 115) {
al_log_error("socket", "Failed to connect: %s (%d).", aki_strerror(errno), errno);
return false;
}
-
break;
}
case AKI_SOCKET_UNIX: {
@@ -217,10 +207,9 @@ bool aki_socket_connect(struct aki_socket *s, str *addr, s32 port)
}
break;
}
- case AKI_SOCKET_UDP: {
+ default:
al_assert(false);
}
- }
signal(SIGPIPE, SIG_IGN);
@@ -239,7 +228,13 @@ ssize_t aki_socket_write(struct aki_socket *s, void *buf, size_t size)
ssize_t aki_socket_sendto(struct aki_socket *s, void *buf, size_t size)
{
- return sendto(s->sock, buf, size, 0, (const struct sockaddr *)&s->addr_un, sizeof(s->addr_un));
+ return sendto(s->sock, buf, size, 0, (const struct sockaddr *)&s->addr_in, sizeof(s->addr_in));
+}
+
+ssize_t aki_socket_recvfrom(struct aki_socket *s, void *buf, size_t size)
+{
+ socklen_t addrlen = sizeof(s->addr_in);
+ return recvfrom(s->sock, buf, size, 0, (struct sockaddr *)&s->addr_in, &addrlen);
}
s32 aki_socket_get_fd(struct aki_socket *s)
diff --git a/src/socket/socket_windows.c b/src/socket/socket_windows.c
index 6e72aea..b83ae52 100644
--- a/src/socket/socket_windows.c
+++ b/src/socket/socket_windows.c
@@ -2,18 +2,6 @@
#include "socket.h"
-static void socket_set_blocking(struct aki_socket *s, bool blocking)
-{
- u_long mode = (blocking) ? 0 : 1;
- ioctlsocket(s->sock, FIONBIO, &mode);
-}
-
-static void socket_set_no_delay(struct aki_socket *s, s32 no_delay)
-{
- (void)s;
- (void)no_delay;
-}
-
bool aki_socket_init(struct aki_socket *s)
{
switch (s->type) {
@@ -33,22 +21,19 @@ bool aki_socket_init(struct aki_socket *s)
return false;
}
- aki_socket_set_blocking(s, s->config.blocking);
- aki_socket_set_no_delay(s, s->config.no_delay);
-
return true;
}
void aki_socket_set_blocking(struct aki_socket *s, bool blocking)
{
- s->config.blocking = blocking;
- socket_set_blocking(s, blocking);
+ u_long mode = (blocking) ? 0 : 1;
+ ioctlsocket(s->sock, FIONBIO, &mode);
}
-void aki_socket_set_no_delay(struct aki_socket *s, bool no_delay)
+void aki_socket_set_no_delay(struct aki_socket *s, s32 no_delay)
{
- s->config.no_delay = no_delay;
- socket_set_no_delay(s, no_delay);
+ (void)s;
+ (void)no_delay;
}
bool aki_socket_listen(struct aki_socket *s, str *addr, s32 port)
@@ -76,9 +61,6 @@ bool aki_socket_accept(struct aki_socket *s, struct aki_socket *c)
return false;
}
- aki_socket_set_blocking(c, c->config.blocking);
- aki_socket_set_no_delay(c, c->config.no_delay);
-
return true;
}