HOLY SHIT IT WORKS

EXCEPT I GET A SIGABRT WHEN THE LINE IS SILENT GOD DAMNIT
This commit is contained in:
reemo 2023-12-20 18:21:13 -06:00
parent f48f399022
commit c07a007731
3 changed files with 85 additions and 18 deletions

View file

@ -67,10 +67,19 @@ int main(int argc, char** argv) {
return -1;
}
char buf[2048], *get;
printf("Connecting to Flashii ...\n");
wsock_t* sock = wsock_open(FII_ADDR, "/", 80);
printf("Authenticating ...\n");
for(;;);
sprintf(buf, "1\tMisuzu\t%s", _G.session);
wsock_send_str(sock, buf);
for(;;) {
wsock_recv(sock, &get);
printf("%s\n", get);
free(get);
}
initscr();
raw(); noecho();

View file

@ -5,8 +5,9 @@
#define WS_REORDER_BUFLEN (sizeof(long double))
inline int _sys_is_net_order() {
return ((char*)(0xB00B))[0] == 0xB0;
int _sys_is_net_order() {
const uint16_t test = 0xB00B;
return ((char*)&test)[0] == 0xB0;
}
void swap_order(char* in, int length) {
@ -176,15 +177,15 @@ int _wsock_read_header(char* head, _ws_head_t* out) {
if((head[0] & 0x70) != 0
|| ((head[0] & 0x0F) > 0x2 && (head[0] & 0x0F) < 0x8)
|| ((head[0] & 0x0F) > 0xA && (head[0] & 0x0F) <= 0xF))
return -1;
return 0;
// invalid parameters check
if((out->opcode == WS_CONT &&
out->first_opcode == WS_OP_UNDEF)
|| (out->opcode != WS_CONT &&
!WS_IS_OP_CTRL(out->opcode) &&
!WS_OP_IS_CTRL(out->opcode) &&
out->first_opcode != WS_OP_UNDEF)
|| (WS_IS_OP_CTRL(out->opcode) && !out->fin))
return -1;
|| (WS_OP_IS_CTRL(out->opcode) && !out->fin))
return 0;
// cache first opcode of fragmented data set
if(out->opcode != WS_CONT && !WS_OP_IS_CTRL(out->opcode))
out->first_opcode = out->opcode;
@ -194,14 +195,16 @@ int _wsock_read_header(char* head, _ws_head_t* out) {
out->body_length = head[1] & 0x7F;
mask_start = 2;
} else if((head[1] & 0x7F) == 0x7E) {
swap_order_copy(head[2], (char*)out->body_length, 2);
swap_order_copy(head + 2, (char*)&out->body_length, 2);
mask_start = 4;
} else {
swap_order_copy(head[2], (char*)out->body_length, 8);
swap_order_copy(head + 2, (char*)&out->body_length, 8);
mask_start = 10;
}
if(out->masked)
memcpy(out->mask, head + mask_start, 4);
return 1;
}
void _wsock_mask(char* mask, char* msg, int length) {
@ -252,7 +255,7 @@ wsock_t* wsock_open
path,
host, port
);
if(send(sock, s_shake, strlen(s_shake), 0) <= 0) {
if(send(sock, s_shake, strlen(s_shake), MSG_NOSIGNAL) <= 0) {
shutdown(sock, SHUT_RDWR);
return NULL;
}
@ -276,7 +279,7 @@ wsock_t* wsock_open
s_shake[total] = '\0';
}
total = end - s_shake + 3;
total = (end - s_shake) + 4;
recv(sock, s_shake, total, 0);
s_shake[total + 1] = '\0';
@ -377,11 +380,12 @@ int wsock_recv(wsock_t* ws, char** out) {
}
char* body;
int body_length = buffer_flush(ws->recv_buf, &packet);
int body_length = buffer_flush(ws->recv_buf, &body);
if(body != NULL) {
if(ws->head_buf.masked)
_ws_mask(body, ws->head_buf.mask, body_length);
if(!WS_PACKET_IS_CTRL(ws->head_buf.opcode)) {
_wsock_mask((char*)ws->head_buf.mask,
body, body_length);
if(!WS_OP_IS_CTRL(ws->head_buf.opcode)) {
buffer_append(ws->frag_buf, body, body_length);
free(body);
}
@ -431,13 +435,63 @@ int wsock_recv(wsock_t* ws, char** out) {
return got;
}
// todo: support sending fragments at some point
int wsock_send_raw
(wsock_t* ws, int opcode, char* body, int length)
(wsock_t* ws, int opcode, char* body, uint64_t length)
{
if(!wsock_is_open(ws))
return -1;
char header[14], *mask;
int header_bsize_len =
(length < 0x7E) ? 0 :
((length <= 0xFFFF) ? 2 : 8);
int header_length =
2 + (length > 0 ? 4 : 0) + header_bsize_len;
header[0] = 0x80 | opcode;
header[1] = 0x80 | ((length < 0x7E) ? length
: (length <= 0xFFFF ? 0x7E : 0x7F));
uint16_t length_u16 = (uint16_t)length;
if(header_bsize_len > 0)
swap_order_copy(
(header_bsize_len == 2
? (char*)&length_u16 : (char*)&length),
header + 2, header_bsize_len);
if(length > 0) {
mask = header + 2 + header_bsize_len;
_wsock_gen_mask(mask);
}
if(send(ws->sock, header,
header_length, MSG_NOSIGNAL) <= 0)
{
wsock_close(ws);
return -1;
}
if(length > 0) {
_wsock_mask(mask, body, length);
if(send(ws->sock, body, length, MSG_NOSIGNAL) <= 0) {
wsock_close(ws);
return -1;
}
_wsock_mask(mask, body, length);
}
return header_length + length;
}
int wsock_send(wsock_t* ws, char* body, int length) {
return wsock_send_raw(ws, WS_BIN, body, length);
}
int wsock_send_str(wsock_t* ws, char* body) {
if(ws->mode & WS_SEND_ALL_BIN)
return wsock_send(ws, body, strlen(body));
else
return wsock_send_raw(ws, WS_TEXT, body, strlen(body));
}
int wsock_is_open(wsock_t* ws) {
@ -449,7 +503,8 @@ void wsock_close(wsock_t* ws) {
return;
const char close_frame[2] = {0x88, 0x00};
send(ws->sock, close_frame, sizeof(close_frame));
send(ws->sock, close_frame,
sizeof(close_frame), MSG_NOSIGNAL);
shutdown(ws->sock, SHUT_RDWR);
ws->sock = -1;
}

View file

@ -7,6 +7,7 @@
#include <sys/types.h>
#include <sys/poll.h>
#include <netdb.h>
#include <errno.h>
/** UTILITIES **/
/*****************/
@ -64,7 +65,9 @@ typedef enum {
// block until a full packet is sent
WS_FULL_SEND = 4,
// receive text frames as binary
WS_RECV_ALL_BIN = 8
WS_RECV_ALL_BIN = 8,
// send text frames as binary
WS_SEND_ALL_BIN = 16
} ws_mode_t;
// mode options that are not mutually exclusive can be
// concatenated using the OR (|) operator. note that
@ -117,7 +120,7 @@ void wsock_mode_set(wsock_t*, int);
int wsock_mode_get(wsock_t*);
int wsock_recv(wsock_t*, char**);
int wsock_send_raw(wsock_t*, int, char*, int);
int wsock_send_raw(wsock_t*, int, char*, uint64_t);
int wsock_send(wsock_t*, char*, int);
int wsock_send_str(wsock_t*, char*);