Attempt windows support (doesn't work)
This commit is contained in:
parent
6cb858f7d2
commit
c50ed2b233
8
Makefile
8
Makefile
@ -3,6 +3,12 @@
|
||||
EMSCR := $(shell command -v emcmake 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:
|
||||
ifndef EMSCR
|
||||
$(error "Emscripten is not in PATH.")
|
||||
@ -27,7 +33,7 @@ FFmpeg/libswscale/libswscale.a: emscr
|
||||
llvm-ar d FFmpeg/libavcodec/libavcodec.a reverse.o
|
||||
|
||||
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
|
||||
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
227
cb64.h
@ -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
|
69
main2.c
69
main2.c
@ -1,3 +1,8 @@
|
||||
#ifdef _WIN32
|
||||
#include<ws2tcpip.h>
|
||||
#include<windows.h>
|
||||
#include"wepoll.c"
|
||||
#else
|
||||
#include<sys/socket.h>
|
||||
#include<sys/epoll.h>
|
||||
#include<netinet/in.h>
|
||||
@ -5,6 +10,7 @@
|
||||
#include<sys/types.h>
|
||||
#include<fcntl.h>
|
||||
#include<unistd.h>
|
||||
#endif
|
||||
|
||||
#include<stdbool.h>
|
||||
#include<string.h>
|
||||
@ -14,13 +20,31 @@
|
||||
#include<errno.h>
|
||||
|
||||
#include"picohttpparser.h"
|
||||
#include"base64.h"
|
||||
#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 Socket;
|
||||
#define closesocket close
|
||||
#endif
|
||||
|
||||
typedef enum ClientType {
|
||||
UNKNOWN,
|
||||
@ -193,7 +217,6 @@ static void stream_step(const uint8_t *newbuf, size_t newsz) {
|
||||
}
|
||||
|
||||
static void receive_ws(Client *cli) {
|
||||
|
||||
}
|
||||
|
||||
static int handle(Client *cli) {
|
||||
@ -238,7 +261,9 @@ static int handle(Client *cli) {
|
||||
char sha1hex[41];
|
||||
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);
|
||||
|
||||
printf("New WS client\n");
|
||||
|
||||
if(Stream.state == STREAMING && Stream.mkvHeader) {
|
||||
printf("Sending header\n");
|
||||
ws_send(cli, Stream.mkvHeader, Stream.mkvHeaderSz);
|
||||
}
|
||||
|
||||
printf("New WS client\n");
|
||||
}
|
||||
|
||||
consume(cli, pret);
|
||||
@ -393,9 +419,6 @@ static bool get_arg_bool(const char *key) {
|
||||
int main(int argc, char **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);
|
||||
if(!streamkey) {
|
||||
puts("Missing stream key parameter key=...");
|
||||
@ -406,13 +429,23 @@ int main(int argc, char **argv) {
|
||||
strcat(ValidStreamPath, "/push/");
|
||||
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")) {
|
||||
setsockopt(ServSock, SOL_SOCKET, SO_REUSEADDR, &(int) {1}, sizeof(int));
|
||||
}
|
||||
setsockopt(ServSock, IPPROTO_IPV6, IPV6_V6ONLY, &(int) {0}, sizeof(int));
|
||||
|
||||
assert(ServSock != -1);
|
||||
|
||||
struct addrinfo *res = NULL;
|
||||
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
|
||||
char buf[BUFSZ];
|
||||
|
||||
#define EPOLL_EVS 2048
|
||||
struct epoll_event events[EPOLL_EVS];
|
||||
int nfds = epoll_wait(EP, events, EPOLL_EVS, -1);
|
||||
|
||||
for(int i = 0; i < nfds; i++) {
|
||||
if(events[i].data.fd == ServSock) {
|
||||
struct sockaddr_storage addr;
|
||||
@ -437,10 +472,14 @@ int main(int argc, char **argv) {
|
||||
|
||||
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) {
|
||||
close(clisock);
|
||||
closesocket(clisock);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
Client *cli = calloc(1, sizeof(*cli));
|
||||
cli->fd = clisock;
|
||||
@ -460,7 +499,7 @@ int main(int argc, char **argv) {
|
||||
while(1) {
|
||||
ssize_t readcount = recv(cli->fd, buf, sizeof(buf), 0);
|
||||
|
||||
if(readcount < 0) {
|
||||
if(readcount <= 0) {
|
||||
if(errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
forceclose = true;
|
||||
}
|
||||
@ -484,7 +523,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
if(forceclose || (events[i].events & (EPOLLRDHUP | EPOLLHUP))) {
|
||||
epoll_ctl(EP, EPOLL_CTL_DEL, cli->fd, NULL);
|
||||
close(cli->fd);
|
||||
closesocket(cli->fd);
|
||||
|
||||
rem_cli(cli);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user