Attempt windows support (doesn't work)

This commit is contained in:
Mid 2025-01-06 11:10:48 +02:00
parent 6cb858f7d2
commit c50ed2b233
3 changed files with 61 additions and 243 deletions

View File

@ -3,6 +3,12 @@
EMSCR := $(shell command -v emcmake 2> /dev/null) EMSCR := $(shell command -v emcmake 2> /dev/null)
LLVM_AR := $(shell command -v llvm-ar 2> /dev/null) LLVM_AR := $(shell command -v llvm-ar 2> /dev/null)
SYS := $(shell $(CC) -dumpmachine)
ifneq (,$(findstring mingw,$(SYS)))
wsrALDFLAGS := -lws2_32
endif
emscr: emscr:
ifndef EMSCR ifndef EMSCR
$(error "Emscripten is not in PATH.") $(error "Emscripten is not in PATH.")
@ -27,7 +33,7 @@ FFmpeg/libswscale/libswscale.a: emscr
llvm-ar d FFmpeg/libavcodec/libavcodec.a reverse.o llvm-ar d FFmpeg/libavcodec/libavcodec.a reverse.o
wsrA: main2.c wsrA: main2.c
cc -s -O3 -D_GNU_SOURCE -o wsrA main2.c picohttpparser.c $(CC) -s -O3 -D_GNU_SOURCE -D_WIN32_WINNT=0x600 -o wsrA main2.c picohttpparser.c base64.c $(wsrALDFLAGS)
support.js: emscr ogg/libogg.a vorbis/lib/libvorbis.a FFmpeg/libswscale/libswscale.a support.js: emscr ogg/libogg.a vorbis/lib/libvorbis.a FFmpeg/libswscale/libswscale.a
emcc -o support -fPIC -flto -IFFmpeg -Iogg/include -Ivorbis/include -LFFmpeg/libavcodec -l:libavcodec.a -LFFmpeg/libswscale -l:libswscale.a -LFFmpeg/libavutil -l:libavutil.a -Lvorbis/lib -l:libvorbis.a -Logg -l:libogg.a support.c -pthread -msimd128 -O3 -sMAYBE_WASM2JS -sUSE_PTHREADS=1 -sEXPORT_ALL=1 -sMAIN_MODULE=1 -sTOTAL_MEMORY=128MB emcc -o support -fPIC -flto -IFFmpeg -Iogg/include -Ivorbis/include -LFFmpeg/libavcodec -l:libavcodec.a -LFFmpeg/libswscale -l:libswscale.a -LFFmpeg/libavutil -l:libavutil.a -Lvorbis/lib -l:libvorbis.a -Logg -l:libogg.a support.c -pthread -msimd128 -O3 -sMAYBE_WASM2JS -sUSE_PTHREADS=1 -sEXPORT_ALL=1 -sMAIN_MODULE=1 -sTOTAL_MEMORY=128MB

227
cb64.h
View File

@ -1,227 +0,0 @@
#ifndef HEADER_CB64_H
#define HEADER_CB64_H
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#define TRUE 1
#define FALSE 0
#define B64_TABLE_SIZE 64
#define B64_ENCODE_OK 0
#define B64_ENCODE_FAIL -1
#define B64_DECODE_OK 0
#define B64_DECODE_FAIL -1
struct base64_table_dict
{
char key;
uint8_t val;
} b64_dict_t;
static struct base64_table_dict dict[B64_TABLE_SIZE];
static const uint8_t BASE_64_TABLE[B64_TABLE_SIZE] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
};
static const uint8_t PADDING = 0x3D;
static const uint8_t SIX_BIT_MASK = 0x3F; // 63 // 111111
static const uint8_t EIGHT_BIT_MASK = 0xFF; // 255 // 11111111
static void init_b64_table_dict()
{
for (int i = 0; i < B64_TABLE_SIZE; i++)
{
b64_dict_t.key = BASE_64_TABLE[i];
b64_dict_t.val = i;
dict[i] = b64_dict_t;
}
}
static struct base64_table_dict base64_table_dict_find(char key)
{
for (int i = 0; i < B64_TABLE_SIZE; i++)
{
if (dict[i].key == key)
return dict[i];
}
return b64_dict_t;
}
static uint64_t size_char_ptr(const unsigned char* arr)
{
uint64_t size = 0;
while(*arr)
{
size++;
arr++;
}
return size;
}
int encode_b64(const unsigned char* src, size_t src_size,
unsigned char** dst, size_t* dst_size)
{
if (src_size == 0)
src_size = size_char_ptr(src);
uint32_t _dst_size = 4 * ((src_size + 2) / 3);
// caller should call free()
unsigned char* _dst = (unsigned char*) malloc(sizeof(*_dst) * _dst_size + 3);
if (_dst == NULL)
return B64_ENCODE_FAIL;
FILE* f = fmemopen((void*)src, src_size, "r");
FILE* base64_res_f = fmemopen((void*)_dst, sizeof(*_dst) * _dst_size + 3, "w");
unsigned char buffer[4];
uint32_t size_out = 0;
uint32_t total_read = 0;
while(TRUE)
{
// read data per 3 bytes to buffer
size_t r = fread(buffer, 1, 3, f);
// check if the entire buffer has been read
if (r <= 0 || total_read == src_size)
break;
total_read += r;
// terminate the buffer with '\0'
buffer[r] = '\0';
uint32_t segment_count = 0;
uint32_t dec = 0;
for (int i = 0; i < r; i++)
{
// if (buffer[i] == '\0')
// continue;
uint32_t l_shift = 16 - segment_count * 8;
uint32_t s = (uint32_t) buffer[i];
dec |= s << l_shift;
segment_count = segment_count + 1;
}
for (int i = 0; i < segment_count+1; i++)
{
uint32_t r_shift = 18 - i * 6;
uint8_t idx_b = (uint8_t) (dec >> r_shift) & SIX_BIT_MASK;
uint8_t c_b64 = BASE_64_TABLE[idx_b];
fputc(c_b64, base64_res_f);
size_out = size_out + 1;
}
if (segment_count == 2)
{
fputc(PADDING, base64_res_f);
size_out = size_out + 2;
}
if (segment_count == 1)
{
fputc(PADDING, base64_res_f);
fputc(PADDING, base64_res_f);
size_out = size_out + 3;
}
}
// terminate the buffer with '\0'
_dst[size_out] = '\0';
*dst = _dst;
*dst_size = size_out;
fclose(f);
fclose(base64_res_f);
return B64_ENCODE_OK;
}
int decode_b64(const unsigned char* src, size_t src_size,
unsigned char** dst, size_t* dst_size)
{
init_b64_table_dict();
if (src_size == 0)
src_size = size_char_ptr(src);
uint32_t _dst_size = src_size / 4 * 3;
// caller should call free()
unsigned char* _dst = (unsigned char*) malloc(sizeof(*_dst) * _dst_size + 1);
if (_dst == NULL)
return B64_DECODE_FAIL;
FILE* base64_in_f = fmemopen((void*)src, src_size, "r");
FILE* text_f = fmemopen((void*)_dst, sizeof(*_dst) * _dst_size + 1, "w");
unsigned char buffer[5];
uint32_t size_out = 0;
uint32_t total_read = 0;
while (TRUE)
{
// read data per 4 bytes to buffer
size_t r = fread(buffer, 1, 4, base64_in_f);
// check if the entire buffer has been read
if (r <= 0 || total_read == src_size)
break;
total_read += r;
// terminate the buffer with '\0'
buffer[r] = '\0';
uint32_t segment_count = 0;
uint32_t dec = 0;
for (int i = 0; i < 4; i++)
{
if (buffer[i] == '\0' || buffer[i] == PADDING)
continue;
struct base64_table_dict b64_idx_dict = base64_table_dict_find(buffer[i]);
uint32_t l_shift = 18 - segment_count * 6;
uint32_t b64_idx = (uint32_t) b64_idx_dict.val;
dec |= b64_idx << l_shift;
segment_count = segment_count + 1;
}
for (int i = 0; i < segment_count-1; i++)
{
uint32_t r_shift = 16 - i * 8;
uint8_t c_b255 = (uint8_t) (dec >> r_shift) & EIGHT_BIT_MASK;
fputc(c_b255, text_f);
size_out = size_out + 1;
}
}
// terminate the buffer with '\0'
_dst[size_out] = '\0';
*dst = _dst;
*dst_size = size_out;
fclose(base64_in_f);
fclose(text_f);
return B64_DECODE_OK;
}
#endif

67
main2.c
View File

@ -1,3 +1,8 @@
#ifdef _WIN32
#include<ws2tcpip.h>
#include<windows.h>
#include"wepoll.c"
#else
#include<sys/socket.h> #include<sys/socket.h>
#include<sys/epoll.h> #include<sys/epoll.h>
#include<netinet/in.h> #include<netinet/in.h>
@ -5,6 +10,7 @@
#include<sys/types.h> #include<sys/types.h>
#include<fcntl.h> #include<fcntl.h>
#include<unistd.h> #include<unistd.h>
#endif
#include<stdbool.h> #include<stdbool.h>
#include<string.h> #include<string.h>
@ -14,13 +20,31 @@
#include<errno.h> #include<errno.h>
#include"picohttpparser.h" #include"picohttpparser.h"
#include"base64.h"
#include"teeny-sha1.c" #include"teeny-sha1.c"
#include"cb64.h"
#define EPOLL_EVS 2048 #ifdef _WIN32
typedef HANDLE EPoll;
typedef int Socket;
void *memmem(const void *haystack, size_t haystack_len, const void * const needle, const size_t needle_len) {
if(haystack == NULL) return NULL;
if(haystack_len == 0) return NULL;
if(needle == NULL) return NULL;
if(needle_len == 0) return NULL;
for(const char *h = haystack; haystack_len >= needle_len; ++h, --haystack_len) {
if(!memcmp(h, needle, needle_len)) {
return (void*) h;
}
}
return NULL;
}
#else
typedef int EPoll; typedef int EPoll;
typedef int Socket; typedef int Socket;
#define closesocket close
#endif
typedef enum ClientType { typedef enum ClientType {
UNKNOWN, UNKNOWN,
@ -193,7 +217,6 @@ static void stream_step(const uint8_t *newbuf, size_t newsz) {
} }
static void receive_ws(Client *cli) { static void receive_ws(Client *cli) {
} }
static int handle(Client *cli) { static int handle(Client *cli) {
@ -238,7 +261,9 @@ static int handle(Client *cli) {
char sha1hex[41]; char sha1hex[41];
sha1digest(sha1bin, sha1hex, acceptbuf, acceptbufsz); sha1digest(sha1bin, sha1hex, acceptbuf, acceptbufsz);
encode_b64(sha1bin, sizeof(sha1bin), &wsAccept, &wsAcceptLen); wsAcceptLen = BASE64_ENCODE_OUT_SIZE(sizeof(sha1bin));
wsAccept = malloc(wsAcceptLen);
base64_encode(sha1bin, sizeof(sha1bin), wsAccept);
} }
} }
@ -266,11 +291,12 @@ static int handle(Client *cli) {
transmit(cli, buf, bufnum); transmit(cli, buf, bufnum);
printf("New WS client\n");
if(Stream.state == STREAMING && Stream.mkvHeader) { if(Stream.state == STREAMING && Stream.mkvHeader) {
printf("Sending header\n");
ws_send(cli, Stream.mkvHeader, Stream.mkvHeaderSz); ws_send(cli, Stream.mkvHeader, Stream.mkvHeaderSz);
} }
printf("New WS client\n");
} }
consume(cli, pret); consume(cli, pret);
@ -393,9 +419,6 @@ static bool get_arg_bool(const char *key) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
Argc = argc, Argv = argv; Argc = argc, Argv = argv;
ServSock = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
EP = epoll_create1(0);
const char *streamkey = get_arg("key", NULL); const char *streamkey = get_arg("key", NULL);
if(!streamkey) { if(!streamkey) {
puts("Missing stream key parameter key=..."); puts("Missing stream key parameter key=...");
@ -406,13 +429,23 @@ int main(int argc, char **argv) {
strcat(ValidStreamPath, "/push/"); strcat(ValidStreamPath, "/push/");
strcat(ValidStreamPath, streamkey); strcat(ValidStreamPath, streamkey);
#ifdef _WIN32
WSAStartup(MAKEWORD(2, 2), &(WSADATA) {});
ServSock = socket(AF_INET6, SOCK_STREAM, 0);
ioctlsocket(ServSock, FIONBIO, &(u_long) {1});
#else
ServSock = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
#endif
EP = epoll_create1(0);
assert(ServSock != -1);
if(get_arg_bool("reuseaddr")) { if(get_arg_bool("reuseaddr")) {
setsockopt(ServSock, SOL_SOCKET, SO_REUSEADDR, &(int) {1}, sizeof(int)); setsockopt(ServSock, SOL_SOCKET, SO_REUSEADDR, &(int) {1}, sizeof(int));
} }
setsockopt(ServSock, IPPROTO_IPV6, IPV6_V6ONLY, &(int) {0}, sizeof(int)); setsockopt(ServSock, IPPROTO_IPV6, IPV6_V6ONLY, &(int) {0}, sizeof(int));
assert(ServSock != -1);
struct addrinfo *res = NULL; struct addrinfo *res = NULL;
assert(getaddrinfo(NULL, get_arg("port", "25404"), &(struct addrinfo) {.ai_flags = AI_PASSIVE, .ai_family = AF_INET6}, &res) == 0); assert(getaddrinfo(NULL, get_arg("port", "25404"), &(struct addrinfo) {.ai_flags = AI_PASSIVE, .ai_family = AF_INET6}, &res) == 0);
@ -428,8 +461,10 @@ int main(int argc, char **argv) {
#define BUFSZ 8192 #define BUFSZ 8192
char buf[BUFSZ]; char buf[BUFSZ];
#define EPOLL_EVS 2048
struct epoll_event events[EPOLL_EVS]; struct epoll_event events[EPOLL_EVS];
int nfds = epoll_wait(EP, events, EPOLL_EVS, -1); int nfds = epoll_wait(EP, events, EPOLL_EVS, -1);
for(int i = 0; i < nfds; i++) { for(int i = 0; i < nfds; i++) {
if(events[i].data.fd == ServSock) { if(events[i].data.fd == ServSock) {
struct sockaddr_storage addr; struct sockaddr_storage addr;
@ -437,10 +472,14 @@ int main(int argc, char **argv) {
Socket clisock = accept(ServSock, (struct sockaddr*) &addr, &addrlen); Socket clisock = accept(ServSock, (struct sockaddr*) &addr, &addrlen);
#ifdef _WIN32
ioctlsocket(clisock, FIONBIO, &(u_long) {1});
#else
if(fcntl(clisock, F_SETFL, fcntl(clisock, F_GETFL, 0) | O_NONBLOCK) == -1) { if(fcntl(clisock, F_SETFL, fcntl(clisock, F_GETFL, 0) | O_NONBLOCK) == -1) {
close(clisock); closesocket(clisock);
continue; continue;
} }
#endif
Client *cli = calloc(1, sizeof(*cli)); Client *cli = calloc(1, sizeof(*cli));
cli->fd = clisock; cli->fd = clisock;
@ -460,7 +499,7 @@ int main(int argc, char **argv) {
while(1) { while(1) {
ssize_t readcount = recv(cli->fd, buf, sizeof(buf), 0); ssize_t readcount = recv(cli->fd, buf, sizeof(buf), 0);
if(readcount < 0) { if(readcount <= 0) {
if(errno != EAGAIN && errno != EWOULDBLOCK) { if(errno != EAGAIN && errno != EWOULDBLOCK) {
forceclose = true; forceclose = true;
} }
@ -484,7 +523,7 @@ int main(int argc, char **argv) {
if(forceclose || (events[i].events & (EPOLLRDHUP | EPOLLHUP))) { if(forceclose || (events[i].events & (EPOLLRDHUP | EPOLLHUP))) {
epoll_ctl(EP, EPOLL_CTL_DEL, cli->fd, NULL); epoll_ctl(EP, EPOLL_CTL_DEL, cli->fd, NULL);
close(cli->fd); closesocket(cli->fd);
rem_cli(cli); rem_cli(cli);