Skip to content

Commit

Permalink
add: complete Windows support
Browse files Browse the repository at this point in the history
This commit adds the final touches for Windows support, now finally working via your favorite Windows compiler.
  • Loading branch information
ThePedroo committed May 9, 2024
1 parent 8845e30 commit 20ab385
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 44 deletions.
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,16 @@ OBJ_DIR = obj

CVERSION = -std=c99
CFLAGS ?= -Ofast -march=native -fno-signed-zeros -fno-trapping-math -funroll-loops
LDFLAGS ?= -Iinclude -Iexternal -Isources -pthread
LDFLAGS ?= -Iinclude -Iexternal -Isources

ifeq ($(OS),Windows_NT)
LDFLAGS += -lwsock32
else
LDFLAGS += -pthread
endif

OPTIONS = -DPORT=$(PORT) -DAUTHORIZATION=\"$(AUTHORIZATION)\" -DALLOW_UNSECURE_RANDOM=$(ALLOW_UNSECURE_RANDOM) $(if $(CSOCKET_SECURE),-DCSOCKET_SECURE -DCSOCKET_KEY=\"$(CSOCKET_KEY)\" -DCSOCKET_CERT=\"$(CSOCKET_CERT)\",) $(if $(TCPLIMITS_EXPERIMENTAL_SAVE_MEMORY),-DTCPLIMITS_EXPERIMENTAL_SAVE_MEMORY,) -DHARDCODED_SESSION_ID=$(HARDCODED_SESSION_ID) -DGITHUB_COMMIT_SHA=\"$(GITHUB_COMMIT_SHA)\" -DGITHUB_BRANCH=\"$(GITHUB_BRANCH)\" -DPCLL_SSL_LIBRARY=$(PCLL_SSL_LIBRARY)
CHECK_FLAGS = -Wpedantic -Wall -Wextra -Werror -Wformat -Wuninitialized -Wshadow
CHECK_FLAGS = -Wpedantic -Wall -Wextra -Werror -Wformat -Wuninitialized -Wshadow -Wno-stringop-overread

SRCS = $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
OBJS = $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(SRCS)))
Expand Down
16 changes: 11 additions & 5 deletions external/csocket-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,19 @@ int csocket_client_init(struct csocket_client *client, bool secure, char *hostna

return -1;
}
#endif

if ((client->socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("[csocket-client]: Failed to create socket");
if ((client->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
perror("[csocket-client]: Failed to create socket");

return -1;
}
return -1;
}
#else
if ((client->socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("[csocket-client]: Failed to create socket");

return -1;
}
#endif

struct hostent *host = gethostbyname(hostname);
if (!host) {
Expand Down
1 change: 1 addition & 0 deletions external/csocket-client.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
struct csocket_client {
#ifdef _WIN32
SOCKET socket;
WSADATA wsa;
#else
int socket;
#endif
Expand Down
38 changes: 30 additions & 8 deletions external/csocket-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

int csocket_server_init(struct csocket_server *server) {
#ifdef _WIN32
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) {
if (WSAStartup(MAKEWORD(2,2), &server->wsa) != 0) {
perror("[csocket-server]: Failed to initialize Winsock");

return -1;
Expand All @@ -40,21 +40,43 @@ int csocket_server_init(struct csocket_server *server) {
}
#endif

if ((server->socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("[csocket-server]: Failed to create socket");
#ifdef _WIN32
server->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server->socket == INVALID_SOCKET) {
perror("[csocket-server]: Failed to create socket");

return -1;
}
return -1;
}
#else
server->socket = socket(AF_INET, SOCK_STREAM, 0);
if (server->socket < 0) {
perror("[csocket-server]: Failed to create socket");

return -1;
}
#endif

struct sockaddr_in serverOptions = {
struct sockaddr_in server_options = {
.sin_addr.s_addr = INADDR_ANY,
.sin_family = AF_INET,
.sin_port = htons(server->port)
};

setsockopt(server->socket, SOL_SOCKET, SO_REUSEADDR, &serverOptions, sizeof(serverOptions));
#ifdef _WIN32
if (setsockopt(server->socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&server_options, sizeof(server_options)) == SOCKET_ERROR) {
perror("[csocket-server]: Failed to set socket options");

return -1;
}
#else
if (setsockopt(server->socket, SOL_SOCKET, SO_REUSEADDR, &server_options, sizeof(server_options)) < 0) {
perror("[csocket-server]: Failed to set socket options");

return -1;
}
#endif

if (bind(server->socket, (struct sockaddr *)&serverOptions, sizeof(serverOptions)) < 0) {
if (bind(server->socket, (struct sockaddr *)&server_options, sizeof(server_options)) < 0) {
perror("[csocket-server]: Failed to bind socket");

return -1;
Expand Down
6 changes: 1 addition & 5 deletions external/csocket-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@ struct csocket_server {

struct csocket_server_client {
int socket;
#ifdef _WIN32
// Not supported yet
#else
struct sockaddr_in address;
#endif
struct sockaddr_in address;
#ifdef CSOCKET_SECURE
SSL *ssl;
#endif
Expand Down
2 changes: 2 additions & 0 deletions external/cthreads.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ int cthreads_cond_destroy(struct cthreads_cond *cond) {
#endif

#ifdef _WIN32
(void) cond;

return 0;
#else
return pthread_cond_destroy(&cond->pCond);
Expand Down
33 changes: 23 additions & 10 deletions external/pdvoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@

#include "pjsonb.h"
#include "jsmn-find.h"
#include "cthreads.h"

#include "httpclient.h"
#include "websocket.h"
#include "utils.h"

/* mingw-64 requires winsock2.h to be included before windows.h */
#include "cthreads.h"

#include "pdvoice.h"

#define PDVOICE_DISCORD_GW_VERSION 4
Expand Down Expand Up @@ -82,12 +84,21 @@ void *_pdvoice_udp(void *data) {
return NULL;
}

int enable = 1;
if (setsockopt(udp_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == -1) {
printf("[pdvoice]: Failed to set UDP socket options.\n");
#ifdef _WIN32
BOOL enable = 1;
if (setsockopt(udp_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&enable, sizeof(BOOL)) == -1) {
printf("[pdvoice]: Failed to set UDP socket options.\n");

return NULL;
}
return NULL;
}
#else
int enable = 1;
if (setsockopt(udp_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == -1) {
printf("[pdvoice]: Failed to set UDP socket options.\n");

return NULL;
}
#endif

struct sockaddr_in udp_server;
udp_server.sin_family = AF_INET;
Expand Down Expand Up @@ -145,7 +156,11 @@ void *_pdvoice_udp(void *data) {

cthreads_mutex_unlock(thread_data->connection->mutex);

int sent = sendto(udp_socket, discovery_buffer, sizeof(discovery_buffer), 0, (struct sockaddr *)&destination, sizeof(destination));
#ifdef _WIN32
int sent = sendto(udp_socket, (const char *)discovery_buffer, sizeof(discovery_buffer), 0, (struct sockaddr *)&destination, sizeof(destination));
#else
int sent = sendto(udp_socket, discovery_buffer, sizeof(discovery_buffer), 0, (struct sockaddr *)&destination, sizeof(destination));
#endif
if (sent == -1) {
perror("[pdvoice]: Failed to send discovery packet to UDP socket");

Expand Down Expand Up @@ -429,9 +444,7 @@ void pdvoice_free(struct pdvoice *connection) {
connection->hb_thread_data = NULL;
}

if ((void *)&connection->ws_thread != NULL) {
cthreads_thread_cancel(connection->ws_thread);
}
cthreads_thread_cancel(connection->ws_thread);

if (connection->ws_connection_info != NULL) {
free(connection->ws_connection_info);
Expand Down
15 changes: 6 additions & 9 deletions lib/httpparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ int httpparser_parse_request(struct httpparser_request *http_request, const char

if (strcmp(http_request->version, "1.1")) return -1;

int i = 0;
int content_length = 0;
struct tstr_string_token last_header = {
.start = 0,
Expand All @@ -79,25 +78,23 @@ int httpparser_parse_request(struct httpparser_request *http_request, const char
struct tstr_string_token header_name;
tstr_find_between(&header_name, request, NULL, header.start, ": ", header.end);

if (header_name.start == 0 || header_name.end == 0) return -1;
if (header_name.start == 0 || header_name.end == 0 || http_request->headers_length >= http_request->headers_max_length) return -1;

int key_length = header_name.end - header_name.start;
int value_length = header.end - header_name.end - 2;

frequenc_fast_copy((char *)request + header_name.start, http_request->headers[i].key, key_length);
_httpparser_to_lower_case(http_request->headers[i].key);
frequenc_fast_copy((char *)request + header_name.end + 2, http_request->headers[i].value, value_length);
frequenc_fast_copy((char *)request + header_name.start, http_request->headers[http_request->headers_length].key, key_length);
_httpparser_to_lower_case(http_request->headers[http_request->headers_length].key);
frequenc_fast_copy((char *)request + header_name.end + 2, http_request->headers[http_request->headers_length].value, value_length);

if (strcmp(http_request->headers[i].key, "content-length") == 0)
if (strcmp(http_request->headers[http_request->headers_length].key, "content-length") == 0)
content_length = atoi(request + header.start + sizeof("content-length: ") - 1);

last_header = header;

i++;
http_request->headers_length++;
}

http_request->headers_length = i;

struct httpparser_header *transfer_encoding_header = httpparser_get_header(http_request, "transfer-encoding");

if (content_length > 0 || transfer_encoding_header != NULL) {
Expand Down
2 changes: 2 additions & 0 deletions lib/httpserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ void *listen_messages(void *args) {
httpparser_init_request(&request, headers, 10);

if (httpparser_parse_request(&request, payload) != 0) {
httpparser_free_request(&request);

printf("[httpparser]: Failed to parse request.\n - Socket: %d\n", csocket_server_client_get_id(&client));

goto invalid_request;
Expand Down
2 changes: 1 addition & 1 deletion lib/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#include "tablec.h"
#include "queryparser.h"
#include "urldecode.h"
#include "cthreads.h"
#include "csocket-server.h"
#include "cthreads.h"
#include "pdvoice.h"
#include "pjsonb.h"

Expand Down
4 changes: 2 additions & 2 deletions lib/track.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ int frequenc_decode_track(struct frequenc_track_info *result, const struct tstr_
}

printf(
"[track]: Successfully decoded track.\n - Version: %d\n - Encoded: %.*s\n - Title: %.*s\n - Author: %.*s\n - Length: %lu\n - Identifier: %.*s\n - Is Stream: %s\n - URI: %.*s\n - Artwork URL: %.*s\n - ISRC: %.*s\n - Source Name: %.*s\n",
"[track]: Successfully decoded track.\n - Version: %d\n - Encoded: %.*s\n - Title: %.*s\n - Author: %.*s\n - Length: %zu\n - Identifier: %.*s\n - Is Stream: %s\n - URI: %.*s\n - Artwork URL: %.*s\n - ISRC: %.*s\n - Source Name: %.*s\n",
version,
(int)track->length, track->string,
(int)result->title.length, result->title.string,
(int)result->author.length, result->author.string,
result->length,
(size_t)result->length,
(int)result->identifier.length, result->identifier.string,
result->is_stream ? "true" : "false",
(int)result->uri.length, result->uri.string,
Expand Down
17 changes: 15 additions & 2 deletions lib/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,25 @@ unsigned int frequenc_safe_seeding(void) {
unsigned int seed = 0;

#ifdef _WIN32
if (rand_s(&seed) != 0) {
HCRYPTPROV hCryptProv;
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
perror("[utils:Windows]: Failed to acquire cryptographic context");

exit(1);
}

if (!CryptGenRandom(hCryptProv, sizeof(seed), (BYTE *) &seed)) {
CryptReleaseContext(hCryptProv, 0);

perror("[utils:Windows]: Failed to generate random seed");

exit(1);
}
#elif __linux__

CryptReleaseContext(hCryptProv, 0);

return seed;
#elif defined __linux__
if (getrandom(&seed, sizeof(seed), 0) == -1) {
perror("[utils:Linux]: Failed to generate random seed");

Expand Down

0 comments on commit 20ab385

Please sign in to comment.