move sock into sys layer
This commit is contained in:
parent
f27ec95481
commit
a504b27767
2
build.c
2
build.c
@ -837,14 +837,12 @@ void OnBuild(StringList cli_args)
|
||||
Bool is_cpp = !is_dir && !is_c && StringEqual(extension, Lit("cpp"));
|
||||
if (is_c || is_cpp) {
|
||||
if (StringBeginsWith(name, Lit("sys_")) ||
|
||||
StringBeginsWith(name, Lit("sock_")) ||
|
||||
StringBeginsWith(name, Lit("gp_")) ||
|
||||
StringBeginsWith(name, Lit("playback_")) ||
|
||||
StringBeginsWith(name, Lit("mp3_")) ||
|
||||
StringBeginsWith(name, Lit("ttf_"))) {
|
||||
if (PlatformWindows) {
|
||||
ignore = !(StringEqual(name, Lit("sys_win32.c")) ||
|
||||
StringEqual(name, Lit("sock_win32.c")) ||
|
||||
StringEqual(name, Lit("gp_dx12.c")) ||
|
||||
StringEqual(name, Lit("playback_wasapi.c")) ||
|
||||
StringEqual(name, Lit("mp3_mmf.c")) ||
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
#include "math.h"
|
||||
#include "gp.h"
|
||||
#include "phys.h"
|
||||
#include "sock.h"
|
||||
#include "host.h"
|
||||
#include "bitbuff.h"
|
||||
|
||||
@ -282,8 +281,7 @@ void sys_app_startup(struct string args_str)
|
||||
gp_startup();
|
||||
|
||||
/* Subsystems */
|
||||
struct sock_startup_receipt sock_sr = sock_startup();
|
||||
struct host_startup_receipt host_sr = host_startup(&sock_sr);
|
||||
struct host_startup_receipt host_sr = host_startup();
|
||||
struct asset_cache_startup_receipt asset_cache_sr = asset_cache_startup();
|
||||
struct ttf_startup_receipt ttf_sr = ttf_startup();
|
||||
struct font_startup_receipt font_sr = font_startup(&asset_cache_sr, &ttf_sr);
|
||||
|
||||
49
src/host.c
49
src/host.c
@ -58,7 +58,7 @@ struct host_channel {
|
||||
|
||||
struct host_channel *next_free;
|
||||
|
||||
struct sock_address address;
|
||||
struct sys_address address;
|
||||
u64 address_hash;
|
||||
struct host_channel *next_address_hash;
|
||||
struct host_channel *prev_address_hash;
|
||||
@ -105,7 +105,7 @@ struct host_channel_lookup_bin {
|
||||
|
||||
struct host_rcv_packet {
|
||||
struct sock *sock;
|
||||
struct sock_address address;
|
||||
struct sys_address address;
|
||||
struct string data;
|
||||
struct host_rcv_packet *next;
|
||||
};
|
||||
@ -162,10 +162,9 @@ INTERNAL void host_msg_assembler_release(struct host_msg_assembler *ma);
|
||||
* Startup
|
||||
* ========================== */
|
||||
|
||||
struct host_startup_receipt host_startup(struct sock_startup_receipt *sock_sr)
|
||||
struct host_startup_receipt host_startup(void)
|
||||
{
|
||||
__prof;
|
||||
(UNUSED)sock_sr;
|
||||
return (struct host_startup_receipt) { 0 };
|
||||
}
|
||||
|
||||
@ -195,14 +194,14 @@ struct host *host_alloc(u16 listen_port)
|
||||
host->num_msg_assembler_lookup_bins = NUM_MSG_ASSEMBLER_LOOKUP_BINS;
|
||||
host->msg_assembler_lookup_bins = arena_push_array(host->arena, struct host_msg_assembler_lookup_bin, host->num_msg_assembler_lookup_bins);
|
||||
|
||||
host->sock = sock_alloc(listen_port, MEBI(2), MEBI(2));
|
||||
host->sock = sys_sock_alloc(listen_port, MEBI(2), MEBI(2));
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
void host_release(struct host *host)
|
||||
{
|
||||
sock_release(host->sock);
|
||||
sys_sock_release(host->sock);
|
||||
|
||||
buddy_ctx_release(host->buddy);
|
||||
arena_release(host->rcv_buffer_write->arena);
|
||||
@ -216,17 +215,17 @@ void host_release(struct host *host)
|
||||
* Channel
|
||||
* ========================== */
|
||||
|
||||
INTERNAL u64 hash_from_address(struct sock_address address)
|
||||
INTERNAL u64 hash_from_address(struct sys_address address)
|
||||
{
|
||||
return hash_fnv64(HASH_FNV64_BASIS, STRING_FROM_STRUCT(&address));
|
||||
}
|
||||
|
||||
INTERNAL struct host_channel *host_channel_from_address(struct host *host, struct sock_address address)
|
||||
INTERNAL struct host_channel *host_channel_from_address(struct host *host, struct sys_address address)
|
||||
{
|
||||
u64 hash = hash_from_address(address);
|
||||
struct host_channel_lookup_bin *bin = &host->channel_lookup_bins[hash % host->num_channel_lookup_bins];
|
||||
for (struct host_channel *channel = bin->first; channel; channel = channel->next_address_hash) {
|
||||
if (channel->address_hash == hash && sock_address_eq(channel->address, address)) {
|
||||
if (channel->address_hash == hash && sys_address_eq(channel->address, address)) {
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
@ -274,7 +273,7 @@ INTERNAL struct host_channel_list host_channels_from_id(struct arena *arena, str
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERNAL struct host_channel *host_channel_alloc(struct host *host, struct sock_address address)
|
||||
INTERNAL struct host_channel *host_channel_alloc(struct host *host, struct sys_address address)
|
||||
{
|
||||
struct host_channel_id id = ZI;
|
||||
struct host_channel *channel;
|
||||
@ -582,7 +581,7 @@ INTERNAL struct host_cmd *host_cmd_alloc_and_append(struct host *host)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void host_queue_connect_to_address(struct host *host, struct sock_address connect_address)
|
||||
void host_queue_connect_to_address(struct host *host, struct sys_address connect_address)
|
||||
{
|
||||
struct host_channel *channel = host_channel_from_address(host, connect_address);
|
||||
if (!channel->valid) {
|
||||
@ -647,14 +646,10 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
|
||||
struct host_rcv_packet *last_packet = 0;
|
||||
{
|
||||
__profn("Read socket");
|
||||
struct sock_array socks = ZI;
|
||||
socks.socks = &host->sock;
|
||||
socks.count = 1;
|
||||
|
||||
struct sock *sock = host->sock;
|
||||
struct sock_read_result res = ZI;
|
||||
while ((res = sock_read(scratch.arena, sock)).valid) {
|
||||
struct sock_address address = res.address;
|
||||
struct sys_sock *sock = host->sock;
|
||||
struct sys_sock_read_result res = ZI;
|
||||
while ((res = sys_sock_read(scratch.arena, sock)).valid) {
|
||||
struct sys_address address = res.address;
|
||||
struct string data = res.data;
|
||||
if (data.len > 0) {
|
||||
struct host_rcv_packet *packet = arena_push(scratch.arena, struct host_rcv_packet);
|
||||
@ -675,7 +670,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
|
||||
__profn("Process host packets");
|
||||
for (struct host_rcv_packet *packet = first_packet; packet; packet = packet->next) {
|
||||
//struct sock *sock = packet->sock;
|
||||
struct sock_address address = packet->address;
|
||||
struct sys_address address = packet->address;
|
||||
struct bitbuff bb = bitbuff_from_string(packet->data);
|
||||
struct bitbuff_reader br = br_from_bitbuff(&bb);
|
||||
u32 magic = br_read_ubits(&br, 32); /* TODO: implicitly encode magic into crc32 */
|
||||
@ -712,7 +707,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
|
||||
{
|
||||
/* A foreign host is trying to connect to us */
|
||||
if (!channel->valid) {
|
||||
logf_info("Host received conection attempt from %F", FMT_STR(sock_string_from_address(scratch.arena, address)));
|
||||
logf_info("Host received conection attempt from %F", FMT_STR(sys_string_from_address(scratch.arena, address)));
|
||||
/* TODO: Verify that some per-host uuid isn't present in a rolling window to prevent reconnects right after a disconnect? */
|
||||
channel = host_channel_alloc(host, address);
|
||||
}
|
||||
@ -725,7 +720,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
|
||||
{
|
||||
/* We successfully connected to a foreign host and they are ready to receive messages */
|
||||
if (channel->valid && !channel->connected) {
|
||||
logf_info("Host received connection from %F", FMT_STR(sock_string_from_address(scratch.arena, address)));
|
||||
logf_info("Host received connection from %F", FMT_STR(sys_string_from_address(scratch.arena, address)));
|
||||
struct host_event *event = push_event(arena, &events);
|
||||
event->kind = HOST_EVENT_KIND_CHANNEL_OPENED;
|
||||
event->channel_id = channel->id;
|
||||
@ -737,7 +732,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
|
||||
{
|
||||
/* A foreign host disconnected from us */
|
||||
if (channel->valid) {
|
||||
logf_info("Host received disconnection from %F", FMT_STR(sock_string_from_address(scratch.arena, address)));
|
||||
logf_info("Host received disconnection from %F", FMT_STR(sys_string_from_address(scratch.arena, address)));
|
||||
struct host_event *event = push_event(arena, &events);
|
||||
event->kind = HOST_EVENT_KIND_CHANNEL_CLOSED;
|
||||
event->channel_id = channel->id;
|
||||
@ -1021,19 +1016,19 @@ void host_update_end(struct host *host)
|
||||
{
|
||||
__profn("Send host packets");
|
||||
for (u64 i = 0; i < host->num_channels_reserved; ++i) {
|
||||
struct sock *sock = host->sock;
|
||||
struct sys_sock *sock = host->sock;
|
||||
struct host_channel *channel = &host->channels[i];
|
||||
u64 total_sent = 0;
|
||||
if (channel->valid) {
|
||||
struct sock_address address = channel->address;
|
||||
struct sys_address address = channel->address;
|
||||
/* Send reliable packets to channel */
|
||||
for (struct host_snd_packet *packet = channel->first_reliable_packet; packet; packet = packet->next) {
|
||||
sock_write(sock, address, STRING(packet->data_len, packet->data));
|
||||
sys_sock_write(sock, address, STRING(packet->data_len, packet->data));
|
||||
total_sent += packet->data_len;
|
||||
}
|
||||
/* Send unreliable packets to channel */
|
||||
for (struct host_snd_packet *packet = channel->first_unreliable_packet; packet; packet = packet->next) {
|
||||
sock_write(sock, address, STRING(packet->data_len, packet->data));
|
||||
sys_sock_write(sock, address, STRING(packet->data_len, packet->data));
|
||||
total_sent += packet->data_len;
|
||||
}
|
||||
/* Release unreliable packets */
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
#define HOST_H
|
||||
|
||||
#include "sys.h"
|
||||
#include "sock.h"
|
||||
#include "snc.h"
|
||||
|
||||
#define HOST_CHANNEL_ID_NIL (struct host_channel_id) { .gen = 0, .idx = 0 }
|
||||
@ -67,7 +66,7 @@ struct host_event_list {
|
||||
struct host {
|
||||
struct arena *arena;
|
||||
|
||||
struct sock *sock;
|
||||
struct sys_sock *sock;
|
||||
|
||||
struct buddy_ctx *buddy; /* For storing msg assembler data */
|
||||
|
||||
@ -104,7 +103,7 @@ struct host {
|
||||
* ========================== */
|
||||
|
||||
struct host_startup_receipt { i32 _; };
|
||||
struct host_startup_receipt host_startup(struct sock_startup_receipt *sock_sr);
|
||||
struct host_startup_receipt host_startup(void);
|
||||
|
||||
/* ========================== *
|
||||
* Host
|
||||
@ -118,7 +117,7 @@ void host_release(struct host *host);
|
||||
* Queue
|
||||
* ========================== */
|
||||
|
||||
void host_queue_connect_to_address(struct host *host, struct sock_address connect_address);
|
||||
void host_queue_connect_to_address(struct host *host, struct sys_address connect_address);
|
||||
|
||||
void host_queue_disconnect(struct host *host, struct host_channel_id channel_id);
|
||||
|
||||
|
||||
49
src/sock.h
49
src/sock.h
@ -1,49 +0,0 @@
|
||||
#ifndef SOCK_H
|
||||
#define SOCK_H
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
enum sock_address_family {
|
||||
SOCK_ADDRESS_FAMILY_IPV4,
|
||||
SOCK_ADDRESS_FAMILY_IPV6
|
||||
};
|
||||
|
||||
struct sock;
|
||||
|
||||
struct sock_array {
|
||||
struct sock **socks;
|
||||
u64 count;
|
||||
};
|
||||
|
||||
struct sock_address {
|
||||
b32 valid;
|
||||
enum sock_address_family family;
|
||||
/* NOTE: ipnb & portnb are stored in network byte order */
|
||||
u8 ipnb[16];
|
||||
u16 portnb;
|
||||
};
|
||||
|
||||
struct sock_read_result {
|
||||
b32 valid; /* Since data.len = 0 can be valid */
|
||||
struct sock_address address;
|
||||
struct string data;
|
||||
};
|
||||
|
||||
struct sock_startup_receipt { i32 _; };
|
||||
struct sock_startup_receipt sock_startup(void);
|
||||
|
||||
struct sock_address sock_address_from_string(struct string str);
|
||||
struct sock_address sock_address_from_port(u16 port);
|
||||
struct string sock_string_from_address(struct arena *arena, struct sock_address address);
|
||||
INLINE b32 sock_address_eq(struct sock_address a, struct sock_address b)
|
||||
{
|
||||
return MEMEQ_STRUCT(&a, &b);
|
||||
}
|
||||
|
||||
struct sock *sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size);
|
||||
void sock_release(struct sock *sock);
|
||||
|
||||
struct sock_read_result sock_read(struct arena *arena, struct sock *sock);
|
||||
void sock_write(struct sock *sock, struct sock_address address, struct string data);
|
||||
|
||||
#endif
|
||||
398
src/sock_win32.c
398
src/sock_win32.c
@ -1,398 +0,0 @@
|
||||
#include "sock.h"
|
||||
#include "sys.h"
|
||||
#include "arena.h"
|
||||
#include "log.h"
|
||||
#include "string.h"
|
||||
#include "gstat.h"
|
||||
#include "snc.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define UNICODE
|
||||
#include <Windows.h>
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
struct win32_address {
|
||||
i32 size;
|
||||
i32 family;
|
||||
union {
|
||||
struct sockaddr_storage sas;
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
};
|
||||
};
|
||||
|
||||
struct win32_sock {
|
||||
SOCKET sock;
|
||||
struct win32_sock *next_free;
|
||||
};
|
||||
|
||||
/* ========================== *
|
||||
* Global state
|
||||
* ========================== */
|
||||
|
||||
GLOBAL struct {
|
||||
WSADATA wsa_data;
|
||||
struct arena *win32_socks_arena;
|
||||
struct snc_mutex win32_socks_mutex;
|
||||
struct win32_sock *first_free_win32_sock;
|
||||
} G = ZI, DEBUG_ALIAS(G, G_sock_win32);
|
||||
|
||||
/* ========================== *
|
||||
* Startup
|
||||
* ========================== */
|
||||
|
||||
struct sock_startup_receipt sock_startup(void)
|
||||
{
|
||||
__prof;
|
||||
/* Startup winsock */
|
||||
WSAStartup(MAKEWORD(2, 2), &G.wsa_data);
|
||||
G.win32_socks_arena = arena_alloc(GIBI(64));
|
||||
return (struct sock_startup_receipt) { 0 };
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Address
|
||||
* ========================== */
|
||||
|
||||
INTERNAL struct sock_address sock_address_from_ip_port_cstr(char *ip_cstr, char *port_cstr)
|
||||
{
|
||||
struct sock_address res = ZI;
|
||||
|
||||
struct addrinfo hints = ZI;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
struct addrinfo *ai_res = 0;
|
||||
i32 status = getaddrinfo(ip_cstr, port_cstr, &hints, &ai_res);
|
||||
if (status == 0) {
|
||||
while (ai_res) {
|
||||
if (ai_res->ai_family == AF_INET) {
|
||||
struct sockaddr_in *sockaddr = (struct sockaddr_in *)ai_res->ai_addr;
|
||||
res.valid = 1;
|
||||
res.family = SOCK_ADDRESS_FAMILY_IPV4;
|
||||
res.portnb = sockaddr->sin_port;
|
||||
STATIC_ASSERT(sizeof(sockaddr->sin_addr) == 4);
|
||||
MEMCPY(res.ipnb, (void *)&sockaddr->sin_addr, 4);
|
||||
break;
|
||||
} else if (ai_res->ai_family == AF_INET6) {
|
||||
/* TODO: Enable ipv6 */
|
||||
#if 0
|
||||
struct sockaddr_in6 *sockaddr = (struct sockaddr_in6 *)ai_res->ai_addr;
|
||||
res.valid = 1;
|
||||
res.family = SOCK_ADDRESS_FAMILY_IPV6;
|
||||
res.portnb = sockaddr->sin6_port;
|
||||
STATIC_ASSERT(sizeof(sockaddr->sin6_addr) == 16);
|
||||
MEMCPY(res.ipnb, (void *)&sockaddr->sin6_addr, 16);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
ai_res = ai_res->ai_next;
|
||||
}
|
||||
freeaddrinfo(ai_res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct sock_address sock_address_from_string(struct string str)
|
||||
{
|
||||
/* Parse string into ip & port */
|
||||
u8 ip_buff[1024];
|
||||
u8 port_buff[countof(ip_buff)];
|
||||
char *ip_cstr = 0;
|
||||
char *port_cstr = 0;
|
||||
{
|
||||
u64 colon_count = 0;
|
||||
for (u64 i = 0; i < str.len; ++i) {
|
||||
u8 c = str.text[i];
|
||||
if (c == ':') {
|
||||
++colon_count;
|
||||
}
|
||||
}
|
||||
u64 ip_len = 0;
|
||||
u64 port_len = 0;
|
||||
u64 parse_len = min_u64(min_u64(str.len, countof(ip_buff) - 1), countof(port_buff) - 1);
|
||||
if (colon_count > 1 && str.text[0] == '[') {
|
||||
/* Parse ipv6 with port */
|
||||
b32 parse_addr = 1;
|
||||
for (u64 i = 1; i < parse_len; ++i) {
|
||||
u8 c = str.text[i];
|
||||
if (parse_addr) {
|
||||
if (c == ']') {
|
||||
parse_addr = 0;
|
||||
} else {
|
||||
ip_buff[ip_len] = c;
|
||||
++ip_len;
|
||||
}
|
||||
} else if (c != ':') {
|
||||
port_buff[port_len] = c;
|
||||
++port_len;
|
||||
}
|
||||
}
|
||||
} else if (colon_count == 1) {
|
||||
/* Parse address with port */
|
||||
b32 parse_addr = 1;
|
||||
for (u64 i = 0; i < parse_len; ++i) {
|
||||
u8 c = str.text[i];
|
||||
if (parse_addr) {
|
||||
if (c == ':') {
|
||||
parse_addr = 0;
|
||||
} else {
|
||||
ip_buff[ip_len] = c;
|
||||
++ip_len;
|
||||
}
|
||||
} else {
|
||||
port_buff[port_len] = c;
|
||||
++port_len;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Copy address without port */
|
||||
ip_len = min_u64(str.len, countof(ip_buff) - 1);
|
||||
MEMCPY(ip_buff, str.text, ip_len);
|
||||
}
|
||||
if (ip_len > 0) {
|
||||
ip_buff[ip_len] = 0;
|
||||
ip_cstr = (char *)ip_buff;
|
||||
}
|
||||
if (port_len > 0) {
|
||||
port_buff[port_len] = 0;
|
||||
port_cstr = (char *)port_buff;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct sock_address res = sock_address_from_ip_port_cstr(ip_cstr, port_cstr);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct sock_address sock_address_from_port(u16 port)
|
||||
{
|
||||
u8 port_buff[128];
|
||||
char *port_cstr = 0;
|
||||
{
|
||||
u8 port_buff_reverse[countof(port_buff)];
|
||||
u64 port_len = 0;
|
||||
while (port > 0 && port_len < (countof(port_buff) - 1)) {
|
||||
u8 digit = port % 10;
|
||||
port /= 10;
|
||||
port_buff_reverse[port_len] = '0' + digit;
|
||||
++port_len;
|
||||
}
|
||||
for (u64 i = 0; i < port_len; ++i) {
|
||||
u64 j = port_len - 1 - i;
|
||||
port_buff[i] = port_buff_reverse[j];
|
||||
}
|
||||
if (port_len > 0) {
|
||||
port_buff[port_len] = 0;
|
||||
port_cstr = (char *)port_buff;
|
||||
}
|
||||
}
|
||||
|
||||
struct sock_address res = sock_address_from_ip_port_cstr(0, port_cstr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct string sock_string_from_address(struct arena *arena, struct sock_address address)
|
||||
{
|
||||
struct string res = ZI;
|
||||
|
||||
if (address.family == SOCK_ADDRESS_FAMILY_IPV6) {
|
||||
/* TODO */
|
||||
} else {
|
||||
u8 ip[4];
|
||||
for (u32 i = 0; i < 4; ++i) {
|
||||
ip[i] = ntohs(address.ipnb[i]);
|
||||
}
|
||||
u16 port = ntohs(address.portnb);
|
||||
res = string_format(arena, LIT("%F.%F.%F.%F:%F"), FMT_UINT(ip[0]), FMT_UINT(ip[1]), FMT_UINT(ip[2]), FMT_UINT(ip[3]), FMT_UINT(port));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERNAL struct win32_address win32_address_from_sock_address(struct sock_address addr)
|
||||
{
|
||||
struct win32_address res = ZI;
|
||||
if (addr.family == SOCK_ADDRESS_FAMILY_IPV4) {
|
||||
res.family = AF_INET;
|
||||
res.size = sizeof(struct sockaddr_in);
|
||||
res.sin.sin_port = addr.portnb;
|
||||
res.sin.sin_family = res.family;
|
||||
MEMCPY(&res.sin.sin_addr, addr.ipnb, 4);
|
||||
} else {
|
||||
res.family = AF_INET6;
|
||||
res.sin6.sin6_port = addr.portnb;
|
||||
res.sin6.sin6_family = res.family;
|
||||
res.size = sizeof(struct sockaddr_in6);
|
||||
MEMCPY(&res.sin6.sin6_addr.s6_addr, addr.ipnb, 16);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* If supplied address has ip INADDR_ANY (0), convert ip to localhost */
|
||||
INTERNAL struct win32_address win32_address_convert_any_to_localhost(struct win32_address addr)
|
||||
{
|
||||
if (addr.family == AF_INET) {
|
||||
u8 *bytes = (u8 *)&addr.sin.sin_addr;
|
||||
b32 is_any = 1;
|
||||
for (u64 i = 0; i < 4; ++i) {
|
||||
if (bytes[i] != 0) {
|
||||
is_any = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_any) {
|
||||
bytes[0] = 127;
|
||||
bytes[3] = 1;
|
||||
}
|
||||
} else if (addr.family == AF_INET6) {
|
||||
u8 *bytes = (u8 *)&addr.sin.sin_addr;
|
||||
b32 is_any = 1;
|
||||
for (u64 i = 0; i < 16; ++i) {
|
||||
if (bytes[i] != 0) {
|
||||
is_any = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_any) {
|
||||
bytes[15] = 1;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
INTERNAL struct sock_address sock_address_from_win32_address(struct win32_address ws_addr)
|
||||
{
|
||||
struct sock_address res = ZI;
|
||||
if (ws_addr.family == AF_INET) {
|
||||
res.family = SOCK_ADDRESS_FAMILY_IPV4;
|
||||
res.portnb = ws_addr.sin.sin_port;
|
||||
MEMCPY(res.ipnb, &ws_addr.sin.sin_addr, 4);
|
||||
res.valid = 1;
|
||||
} else if (ws_addr.family == AF_INET6) {
|
||||
res.family = SOCK_ADDRESS_FAMILY_IPV6;
|
||||
res.portnb = ws_addr.sin6.sin6_port;
|
||||
MEMCPY(res.ipnb, &ws_addr.sin6.sin6_addr.s6_addr, 16);
|
||||
res.valid = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Sock
|
||||
* ========================== */
|
||||
|
||||
struct sock *sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size)
|
||||
{
|
||||
struct win32_sock *ws = 0;
|
||||
{
|
||||
struct snc_lock lock = snc_lock_e(&G.win32_socks_mutex);
|
||||
if (G.first_free_win32_sock) {
|
||||
ws = G.first_free_win32_sock;
|
||||
G.first_free_win32_sock = ws->next_free;
|
||||
} else {
|
||||
ws = arena_push_no_zero(G.win32_socks_arena, struct win32_sock);
|
||||
}
|
||||
snc_unlock(&lock);
|
||||
}
|
||||
MEMZERO_STRUCT(ws);
|
||||
struct sock_address addr = sock_address_from_port(listen_port);
|
||||
struct win32_address bind_address = win32_address_from_sock_address(addr);
|
||||
ws->sock = socket(bind_address.family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
{
|
||||
i32 sb = sndbuf_size;
|
||||
i32 rb = rcvbuf_size;
|
||||
setsockopt(ws->sock, SOL_SOCKET, SO_SNDBUF, (char *)&sb, sizeof(sb));
|
||||
setsockopt(ws->sock, SOL_SOCKET, SO_RCVBUF, (char *)&rb, sizeof(rb));
|
||||
}
|
||||
|
||||
bind(ws->sock, &bind_address.sa, bind_address.size);
|
||||
u32 imode = 1;
|
||||
ioctlsocket(ws->sock, FIONBIO, (unsigned long *)&imode);
|
||||
|
||||
return (struct sock *)ws;
|
||||
}
|
||||
|
||||
void sock_release(struct sock *sock)
|
||||
{
|
||||
struct win32_sock *ws = (struct win32_sock *)sock;
|
||||
closesocket(ws->sock);
|
||||
struct snc_lock lock = snc_lock_e(&G.win32_socks_mutex);
|
||||
{
|
||||
ws->next_free = G.first_free_win32_sock;
|
||||
G.first_free_win32_sock = ws;
|
||||
}
|
||||
snc_unlock(&lock);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Read
|
||||
* ========================== */
|
||||
|
||||
struct sock_read_result sock_read(struct arena *arena, struct sock *sock)
|
||||
{
|
||||
struct win32_sock *ws = (struct win32_sock *)sock;
|
||||
|
||||
u64 read_buff_size = KIBI(64);
|
||||
struct string read_buff = ZI;
|
||||
read_buff.len = read_buff_size;
|
||||
read_buff.text = arena_push_array_no_zero(arena, u8, read_buff_size);
|
||||
|
||||
struct sock_read_result res = ZI;
|
||||
|
||||
struct win32_address ws_addr = ZI;
|
||||
ws_addr.size = sizeof(ws_addr.sas);
|
||||
|
||||
i32 size = recvfrom(ws->sock, (char *)read_buff.text, read_buff.len, 0, &ws_addr.sa, &ws_addr.size);
|
||||
ws_addr.family = ws_addr.sin.sin_family;
|
||||
|
||||
res.address = sock_address_from_win32_address(ws_addr);
|
||||
if (size >= 0) {
|
||||
gstat_add(GSTAT_SOCK_BYTES_RECEIVED, size);
|
||||
res.data.text = read_buff.text;
|
||||
res.data.len = size;
|
||||
res.valid = 1;
|
||||
|
||||
/* Pop arena back to end of msg */
|
||||
arena_pop_to(arena, arena->pos - read_buff_size + size);
|
||||
} else {
|
||||
#if RTC
|
||||
i32 err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK && err != WSAETIMEDOUT && err != WSAECONNRESET) {
|
||||
ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Write
|
||||
* ========================== */
|
||||
|
||||
void sock_write(struct sock *sock, struct sock_address address, struct string data)
|
||||
{
|
||||
struct win32_sock *ws = (struct win32_sock *)sock;
|
||||
struct win32_address ws_addr = win32_address_from_sock_address(address);
|
||||
i32 size = sendto(ws->sock, (char *)data.text, data.len, 0, &ws_addr.sa, ws_addr.size);
|
||||
if (size > 0) {
|
||||
gstat_add(GSTAT_SOCK_BYTES_SENT, size);
|
||||
}
|
||||
#if RTC
|
||||
if (size != (i32)data.len) {
|
||||
i32 err = WSAGetLastError();
|
||||
(UNUSED)err;
|
||||
ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
38
src/sys.h
38
src/sys.h
@ -527,6 +527,44 @@ void sys_message_box(enum sys_message_box_kind kind, struct string message);
|
||||
void sys_set_clipboard_text(struct string str);
|
||||
struct string sys_get_clipboard_text(struct arena *arena);
|
||||
|
||||
/* ========================== *
|
||||
* Address
|
||||
* ========================== */
|
||||
|
||||
enum sys_address_family {
|
||||
SYS_ADDRESS_FAMILY_IPV4,
|
||||
SYS_ADDRESS_FAMILY_IPV6
|
||||
};
|
||||
|
||||
struct sys_address {
|
||||
b32 valid;
|
||||
enum sys_address_family family;
|
||||
/* NOTE: ipnb & portnb are stored in network byte order */
|
||||
u8 ipnb[16];
|
||||
u16 portnb;
|
||||
};
|
||||
|
||||
struct sys_address sys_address_from_string(struct string str);
|
||||
struct sys_address sys_address_from_port(u16 port);
|
||||
struct string sys_string_from_address(struct arena *arena, struct sys_address address);
|
||||
b32 sys_address_eq(struct sys_address a, struct sys_address b);
|
||||
|
||||
/* ========================== *
|
||||
* Sock
|
||||
* ========================== */
|
||||
|
||||
struct sys_sock_read_result {
|
||||
b32 valid; /* Since data.len = 0 can be valid */
|
||||
struct sys_address address;
|
||||
struct string data;
|
||||
};
|
||||
|
||||
struct sys_sock *sys_sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size);
|
||||
void sys_sock_release(struct sys_sock *sock);
|
||||
|
||||
struct sys_sock_read_result sys_sock_read(struct arena *arena, struct sys_sock *sock);
|
||||
void sys_sock_write(struct sys_sock *sock, struct sys_address address, struct string data);
|
||||
|
||||
/* ========================== *
|
||||
* Util
|
||||
* ========================== */
|
||||
|
||||
381
src/sys_win32.c
381
src/sys_win32.c
@ -9,17 +9,22 @@
|
||||
#include "util.h"
|
||||
#include "uni.h"
|
||||
#include "resource.h"
|
||||
#include "gstat.h"
|
||||
|
||||
#pragma warning(push, 0)
|
||||
# define UNICODE
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <Windows.h>
|
||||
# include <WinSock2.h>
|
||||
# include <TlHelp32.h>
|
||||
# include <WS2tcpip.h>
|
||||
# include <windowsx.h>
|
||||
# include <ShlObj_core.h>
|
||||
# include <fileapi.h>
|
||||
# include <dwmapi.h>
|
||||
# include <bcrypt.h>
|
||||
# include <avrt.h>
|
||||
# include <TlHelp32.h>
|
||||
# include <shellapi.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#pragma comment(lib, "kernel32")
|
||||
@ -31,6 +36,7 @@
|
||||
#pragma comment(lib, "bcrypt")
|
||||
#pragma comment(lib, "synchronization")
|
||||
#pragma comment(lib, "avrt")
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
#define SYS_WINDOW_EVENT_LISTENERS_MAX 512
|
||||
#define WINDOW_CLASS_NAME L"power_play_window_class"
|
||||
@ -115,6 +121,22 @@ struct win32_window {
|
||||
struct win32_window *next_free;
|
||||
};
|
||||
|
||||
struct win32_address {
|
||||
i32 size;
|
||||
i32 family;
|
||||
union {
|
||||
struct sockaddr_storage sas;
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
};
|
||||
};
|
||||
|
||||
struct win32_sock {
|
||||
SOCKET sock;
|
||||
struct win32_sock *next_free;
|
||||
};
|
||||
|
||||
struct alignas(64) wait_list {
|
||||
u64 value;
|
||||
i16 first_waiter;
|
||||
@ -292,6 +314,12 @@ GLOBAL struct {
|
||||
struct arena *windows_arena;
|
||||
struct win32_window *first_free_window;
|
||||
|
||||
/* Sockets pool */
|
||||
WSADATA wsa_data;
|
||||
struct arena *socks_arena;
|
||||
struct snc_mutex socks_mutex;
|
||||
struct win32_sock *first_free_sock;
|
||||
|
||||
|
||||
|
||||
/* Exit funcs */
|
||||
@ -3129,6 +3157,347 @@ u32 sys_num_logical_processors(void)
|
||||
return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Address
|
||||
* ========================== */
|
||||
|
||||
INTERNAL struct sys_address sys_address_from_ip_port_cstr(char *ip_cstr, char *port_cstr)
|
||||
{
|
||||
struct sys_address res = ZI;
|
||||
|
||||
struct addrinfo hints = ZI;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
struct addrinfo *ai_res = 0;
|
||||
i32 status = getaddrinfo(ip_cstr, port_cstr, &hints, &ai_res);
|
||||
if (status == 0) {
|
||||
while (ai_res) {
|
||||
if (ai_res->ai_family == AF_INET) {
|
||||
struct sockaddr_in *sockaddr = (struct sockaddr_in *)ai_res->ai_addr;
|
||||
res.valid = 1;
|
||||
res.family = SYS_ADDRESS_FAMILY_IPV4;
|
||||
res.portnb = sockaddr->sin_port;
|
||||
STATIC_ASSERT(sizeof(sockaddr->sin_addr) == 4);
|
||||
MEMCPY(res.ipnb, (void *)&sockaddr->sin_addr, 4);
|
||||
break;
|
||||
} else if (ai_res->ai_family == AF_INET6) {
|
||||
/* TODO: Enable ipv6 */
|
||||
#if 0
|
||||
struct sockaddr_in6 *sockaddr = (struct sockaddr_in6 *)ai_res->ai_addr;
|
||||
res.valid = 1;
|
||||
res.family = SYS_ADDRESS_FAMILY_IPV6;
|
||||
res.portnb = sockaddr->sin6_port;
|
||||
STATIC_ASSERT(sizeof(sockaddr->sin6_addr) == 16);
|
||||
MEMCPY(res.ipnb, (void *)&sockaddr->sin6_addr, 16);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
ai_res = ai_res->ai_next;
|
||||
}
|
||||
freeaddrinfo(ai_res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct sys_address sys_address_from_string(struct string str)
|
||||
{
|
||||
/* Parse string into ip & port */
|
||||
u8 ip_buff[1024];
|
||||
u8 port_buff[countof(ip_buff)];
|
||||
char *ip_cstr = 0;
|
||||
char *port_cstr = 0;
|
||||
{
|
||||
u64 colon_count = 0;
|
||||
for (u64 i = 0; i < str.len; ++i) {
|
||||
u8 c = str.text[i];
|
||||
if (c == ':') {
|
||||
++colon_count;
|
||||
}
|
||||
}
|
||||
u64 ip_len = 0;
|
||||
u64 port_len = 0;
|
||||
u64 parse_len = min_u64(min_u64(str.len, countof(ip_buff) - 1), countof(port_buff) - 1);
|
||||
if (colon_count > 1 && str.text[0] == '[') {
|
||||
/* Parse ipv6 with port */
|
||||
b32 parse_addr = 1;
|
||||
for (u64 i = 1; i < parse_len; ++i) {
|
||||
u8 c = str.text[i];
|
||||
if (parse_addr) {
|
||||
if (c == ']') {
|
||||
parse_addr = 0;
|
||||
} else {
|
||||
ip_buff[ip_len] = c;
|
||||
++ip_len;
|
||||
}
|
||||
} else if (c != ':') {
|
||||
port_buff[port_len] = c;
|
||||
++port_len;
|
||||
}
|
||||
}
|
||||
} else if (colon_count == 1) {
|
||||
/* Parse address with port */
|
||||
b32 parse_addr = 1;
|
||||
for (u64 i = 0; i < parse_len; ++i) {
|
||||
u8 c = str.text[i];
|
||||
if (parse_addr) {
|
||||
if (c == ':') {
|
||||
parse_addr = 0;
|
||||
} else {
|
||||
ip_buff[ip_len] = c;
|
||||
++ip_len;
|
||||
}
|
||||
} else {
|
||||
port_buff[port_len] = c;
|
||||
++port_len;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Copy address without port */
|
||||
ip_len = min_u64(str.len, countof(ip_buff) - 1);
|
||||
MEMCPY(ip_buff, str.text, ip_len);
|
||||
}
|
||||
if (ip_len > 0) {
|
||||
ip_buff[ip_len] = 0;
|
||||
ip_cstr = (char *)ip_buff;
|
||||
}
|
||||
if (port_len > 0) {
|
||||
port_buff[port_len] = 0;
|
||||
port_cstr = (char *)port_buff;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct sys_address res = sys_address_from_ip_port_cstr(ip_cstr, port_cstr);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct sys_address sys_address_from_port(u16 port)
|
||||
{
|
||||
u8 port_buff[128];
|
||||
char *port_cstr = 0;
|
||||
{
|
||||
u8 port_buff_reverse[countof(port_buff)];
|
||||
u64 port_len = 0;
|
||||
while (port > 0 && port_len < (countof(port_buff) - 1)) {
|
||||
u8 digit = port % 10;
|
||||
port /= 10;
|
||||
port_buff_reverse[port_len] = '0' + digit;
|
||||
++port_len;
|
||||
}
|
||||
for (u64 i = 0; i < port_len; ++i) {
|
||||
u64 j = port_len - 1 - i;
|
||||
port_buff[i] = port_buff_reverse[j];
|
||||
}
|
||||
if (port_len > 0) {
|
||||
port_buff[port_len] = 0;
|
||||
port_cstr = (char *)port_buff;
|
||||
}
|
||||
}
|
||||
|
||||
struct sys_address res = sys_address_from_ip_port_cstr(0, port_cstr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct string sys_string_from_address(struct arena *arena, struct sys_address address)
|
||||
{
|
||||
struct string res = ZI;
|
||||
|
||||
if (address.family == SYS_ADDRESS_FAMILY_IPV6) {
|
||||
/* TODO */
|
||||
} else {
|
||||
u8 ip[4];
|
||||
for (u32 i = 0; i < 4; ++i) {
|
||||
ip[i] = ntohs(address.ipnb[i]);
|
||||
}
|
||||
u16 port = ntohs(address.portnb);
|
||||
res = string_format(arena, LIT("%F.%F.%F.%F:%F"), FMT_UINT(ip[0]), FMT_UINT(ip[1]), FMT_UINT(ip[2]), FMT_UINT(ip[3]), FMT_UINT(port));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
b32 sys_address_eq(struct sys_address a, struct sys_address b)
|
||||
{
|
||||
return MEMEQ_STRUCT(&a, &b);
|
||||
}
|
||||
|
||||
INTERNAL struct win32_address win32_address_from_sys_address(struct sys_address addr)
|
||||
{
|
||||
struct win32_address res = ZI;
|
||||
if (addr.family == SYS_ADDRESS_FAMILY_IPV4) {
|
||||
res.family = AF_INET;
|
||||
res.size = sizeof(struct sockaddr_in);
|
||||
res.sin.sin_port = addr.portnb;
|
||||
res.sin.sin_family = res.family;
|
||||
MEMCPY(&res.sin.sin_addr, addr.ipnb, 4);
|
||||
} else {
|
||||
res.family = AF_INET6;
|
||||
res.sin6.sin6_port = addr.portnb;
|
||||
res.sin6.sin6_family = res.family;
|
||||
res.size = sizeof(struct sockaddr_in6);
|
||||
MEMCPY(&res.sin6.sin6_addr.s6_addr, addr.ipnb, 16);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* If supplied address has ip INADDR_ANY (0), convert ip to localhost */
|
||||
INTERNAL struct win32_address win32_address_convert_any_to_localhost(struct win32_address addr)
|
||||
{
|
||||
if (addr.family == AF_INET) {
|
||||
u8 *bytes = (u8 *)&addr.sin.sin_addr;
|
||||
b32 is_any = 1;
|
||||
for (u64 i = 0; i < 4; ++i) {
|
||||
if (bytes[i] != 0) {
|
||||
is_any = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_any) {
|
||||
bytes[0] = 127;
|
||||
bytes[3] = 1;
|
||||
}
|
||||
} else if (addr.family == AF_INET6) {
|
||||
u8 *bytes = (u8 *)&addr.sin.sin_addr;
|
||||
b32 is_any = 1;
|
||||
for (u64 i = 0; i < 16; ++i) {
|
||||
if (bytes[i] != 0) {
|
||||
is_any = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_any) {
|
||||
bytes[15] = 1;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
INTERNAL struct sys_address sys_address_from_win32_address(struct win32_address ws_addr)
|
||||
{
|
||||
struct sys_address res = ZI;
|
||||
if (ws_addr.family == AF_INET) {
|
||||
res.family = SYS_ADDRESS_FAMILY_IPV4;
|
||||
res.portnb = ws_addr.sin.sin_port;
|
||||
MEMCPY(res.ipnb, &ws_addr.sin.sin_addr, 4);
|
||||
res.valid = 1;
|
||||
} else if (ws_addr.family == AF_INET6) {
|
||||
res.family = SYS_ADDRESS_FAMILY_IPV6;
|
||||
res.portnb = ws_addr.sin6.sin6_port;
|
||||
MEMCPY(res.ipnb, &ws_addr.sin6.sin6_addr.s6_addr, 16);
|
||||
res.valid = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* ========================== *
|
||||
* Sock
|
||||
* ========================== */
|
||||
|
||||
struct sys_sock *sys_sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size)
|
||||
{
|
||||
struct win32_sock *ws = 0;
|
||||
{
|
||||
struct snc_lock lock = snc_lock_e(&G.socks_mutex);
|
||||
if (G.first_free_sock) {
|
||||
ws = G.first_free_sock;
|
||||
G.first_free_sock = ws->next_free;
|
||||
} else {
|
||||
ws = arena_push_no_zero(G.socks_arena, struct win32_sock);
|
||||
}
|
||||
snc_unlock(&lock);
|
||||
}
|
||||
MEMZERO_STRUCT(ws);
|
||||
|
||||
struct sys_address addr = sys_address_from_port(listen_port);
|
||||
struct win32_address bind_address = win32_address_from_sys_address(addr);
|
||||
ws->sock = socket(bind_address.family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
{
|
||||
i32 sb = sndbuf_size;
|
||||
i32 rb = rcvbuf_size;
|
||||
u32 imode = 1;
|
||||
setsockopt(ws->sock, SOL_SOCKET, SO_SNDBUF, (char *)&sb, sizeof(sb));
|
||||
setsockopt(ws->sock, SOL_SOCKET, SO_RCVBUF, (char *)&rb, sizeof(rb));
|
||||
ioctlsocket(ws->sock, FIONBIO, (unsigned long *)&imode);
|
||||
}
|
||||
bind(ws->sock, &bind_address.sa, bind_address.size);
|
||||
|
||||
return (struct sys_sock *)ws;
|
||||
}
|
||||
|
||||
void sys_sock_release(struct sys_sock *sock)
|
||||
{
|
||||
struct win32_sock *ws = (struct win32_sock *)sock;
|
||||
closesocket(ws->sock);
|
||||
struct snc_lock lock = snc_lock_e(&G.socks_mutex);
|
||||
{
|
||||
ws->next_free = G.first_free_sock;
|
||||
G.first_free_sock = ws;
|
||||
}
|
||||
snc_unlock(&lock);
|
||||
}
|
||||
|
||||
struct sys_sock_read_result sys_sock_read(struct arena *arena, struct sys_sock *sock)
|
||||
{
|
||||
struct win32_sock *ws = (struct win32_sock *)sock;
|
||||
|
||||
u64 read_buff_size = KIBI(64);
|
||||
struct string read_buff = ZI;
|
||||
read_buff.len = read_buff_size;
|
||||
read_buff.text = arena_push_array_no_zero(arena, u8, read_buff_size);
|
||||
|
||||
struct sys_sock_read_result res = ZI;
|
||||
|
||||
struct win32_address ws_addr = ZI;
|
||||
ws_addr.size = sizeof(ws_addr.sas);
|
||||
|
||||
i32 size = recvfrom(ws->sock, (char *)read_buff.text, read_buff.len, 0, &ws_addr.sa, &ws_addr.size);
|
||||
ws_addr.family = ws_addr.sin.sin_family;
|
||||
|
||||
res.address = sys_address_from_win32_address(ws_addr);
|
||||
if (size >= 0) {
|
||||
gstat_add(GSTAT_SOCK_BYTES_RECEIVED, size);
|
||||
res.data.text = read_buff.text;
|
||||
res.data.len = size;
|
||||
res.valid = 1;
|
||||
|
||||
/* Pop arena back to end of msg */
|
||||
arena_pop_to(arena, arena->pos - read_buff_size + size);
|
||||
} else {
|
||||
#if RTC
|
||||
i32 err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK && err != WSAETIMEDOUT && err != WSAECONNRESET) {
|
||||
ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void sys_sock_write(struct sys_sock *sock, struct sys_address address, struct string data)
|
||||
{
|
||||
struct win32_sock *ws = (struct win32_sock *)sock;
|
||||
struct win32_address ws_addr = win32_address_from_sys_address(address);
|
||||
i32 size = sendto(ws->sock, (char *)data.text, data.len, 0, &ws_addr.sa, ws_addr.size);
|
||||
if (size > 0) {
|
||||
gstat_add(GSTAT_SOCK_BYTES_SENT, size);
|
||||
}
|
||||
#if RTC
|
||||
if (size != (i32)data.len) {
|
||||
i32 err = WSAGetLastError();
|
||||
(UNUSED)err;
|
||||
ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Entry point
|
||||
* ========================== */
|
||||
@ -3273,15 +3642,19 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
|
||||
/* Query system info */
|
||||
GetSystemInfo(&G.info);
|
||||
|
||||
/* Set up threads */
|
||||
/* Init threads pool */
|
||||
G.threads_arena = arena_alloc(GIBI(64));
|
||||
|
||||
/* Set up watches */
|
||||
/* Init watches pool */
|
||||
G.watches_arena = arena_alloc(GIBI(64));
|
||||
|
||||
/* Set up windows */
|
||||
/* Init windows pool */
|
||||
G.windows_arena = arena_alloc(GIBI(64));
|
||||
|
||||
/* Init winsock */
|
||||
WSAStartup(MAKEWORD(2, 2), &G.wsa_data);
|
||||
G.socks_arena = arena_alloc(GIBI(64));
|
||||
|
||||
/* Initialize vk table */
|
||||
win32_init_vk_btn_table();
|
||||
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include "collider.h"
|
||||
#include "rand.h"
|
||||
#include "log.h"
|
||||
#include "sock.h"
|
||||
#include "host.h"
|
||||
#include "bitbuff.h"
|
||||
#include "gstat.h"
|
||||
@ -2163,7 +2162,7 @@ INTERNAL SYS_JOB_DEF(local_sim_job, _)
|
||||
struct host *host;
|
||||
if (G.connect_address_str.len > 0) {
|
||||
host = host_alloc(0);
|
||||
struct sock_address addr = sock_address_from_string(G.connect_address_str);
|
||||
struct sys_address addr = sys_address_from_string(G.connect_address_str);
|
||||
host_queue_connect_to_address(host, addr);
|
||||
} else {
|
||||
host = host_alloc(12345);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user