postnummer-app/backend/linux.c

99 lines
2.7 KiB
C
Raw Normal View History

2023-02-10 16:39:04 +00:00
#include "tcp.h"
#include <arpa/inet.h>
2023-02-13 00:47:36 +00:00
#include <errno.h>
2023-02-10 16:39:04 +00:00
#include <netinet/in.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
2023-02-13 00:47:36 +00:00
#include <string.h>
2023-02-10 16:39:04 +00:00
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
2023-02-09 12:37:00 +00:00
2023-02-10 16:39:04 +00:00
struct TcpServer {
int server_socket;
struct sockaddr_in server_address;
};
struct TcpConnection {
int client_socket;
struct sockaddr_in client_address;
};
void tcp_global_initialize_sockets(void) { }
TcpServer* tcp_server_create(const char* ip, uint16_t port)
{
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
printf("error: tcp: could not open socket\n");
return NULL;
}
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) {
printf("warning: tcp: could not setsockopt SO_REUSEADDR\n");
}
struct sockaddr_in server_address;
server_address.sin_addr.s_addr = inet_addr(ip);
server_address.sin_family = AF_INET;
server_address.sin_port = htons(port);
if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
printf("error: tcp: could not bind socket\n");
2023-02-13 00:47:36 +00:00
close(server_socket);
2023-02-10 16:39:04 +00:00
return NULL;
}
2023-02-13 00:47:36 +00:00
if (listen(server_socket, SOMAXCONN - 1) < 0) {
2023-02-10 16:39:04 +00:00
printf("error: tcp: could not listen on server\n");
2023-02-13 00:47:36 +00:00
close(server_socket);
2023-02-10 16:39:04 +00:00
return NULL;
}
TcpServer* self = malloc(sizeof(TcpServer));
*self = (TcpServer) {
.server_socket = server_socket,
.server_address = server_address,
};
return self;
}
void tcp_server_destroy(TcpServer* server)
{
close(server->server_socket);
free(server);
}
TcpConnection* tcp_server_accept(TcpServer* server)
{
2023-02-13 00:47:36 +00:00
struct sockaddr_in client_address = { 0 };
socklen_t client_size = 0;
2023-02-10 16:39:04 +00:00
int client_socket
= accept(server->server_socket, (struct sockaddr*)&client_address, &client_size);
if (client_socket < 0) {
printf("error: tcp: could not accept connection\n");
2023-02-13 00:47:36 +00:00
printf("errno: %d %s\n", errno, strerror(errno));
2023-02-10 16:39:04 +00:00
return NULL;
}
TcpConnection* connection = malloc(sizeof(TcpConnection));
*connection = (TcpConnection) {
.client_socket = client_socket,
.client_address = client_address,
};
return connection;
}
void tcp_connection_destroy(TcpConnection* connection)
2023-02-09 12:37:00 +00:00
{
2023-02-10 16:39:04 +00:00
close(connection->client_socket);
free(connection);
2023-02-09 12:37:00 +00:00
}
2023-02-10 16:39:04 +00:00
ssize_t tcp_recieve(TcpConnection* connection, uint8_t* data, size_t amount)
2023-02-09 12:37:00 +00:00
{
2023-02-10 16:39:04 +00:00
return recv(connection->client_socket, data, amount, 0);
2023-02-09 12:37:00 +00:00
}
2023-02-10 16:39:04 +00:00
ssize_t tcp_send(TcpConnection* connection, uint8_t* data, size_t amount)
{
return send(connection->client_socket, data, amount, 0);
}