wsock handshake works

This commit is contained in:
reemo 2023-12-17 08:30:44 -06:00
parent 53272e629d
commit 2766e50f47
4 changed files with 188 additions and 5 deletions

3
.gitignore vendored
View file

@ -36,6 +36,7 @@
*.i*86 *.i*86
*.x86_64 *.x86_64
*.hex *.hex
clii
# Debug files # Debug files
*.dSYM/ *.dSYM/
@ -51,4 +52,4 @@ modules.order
Module.symvers Module.symvers
Mkfile.old Mkfile.old
dkms.conf dkms.conf
*.swp

View file

@ -67,6 +67,7 @@ int main(int argc, char** argv) {
} }
printf("Connecting to Flashii ...\n"); printf("Connecting to Flashii ...\n");
wsock_t* sock = wsock_open(FII_ADDR, "/", 80);
for(;;); for(;;);

View file

@ -1,3 +1,178 @@
#include "wsock.h" #include "wsock.h"
/** DATA BUFFER **/
/*******************/
buffer_t* buffer_create() {
buffer_t* buf = malloc(sizeof(buffer_t));
buf->data = NULL;
buf->next = NULL;
buf->length = 0;
return buf;
}
int buffer_is_empty(buffer_t* buf) {
return buf->data == NULL;
}
int buffer_length(buffer_t* buf) {
if(buf == NULL)
return 0;
return buf->length + buffer_length(buf->next);
}
void buffer_append
(buffer_t* buf, const char* data, int length)
{
if(buf->data != NULL) {
buf->next = buffer_create();
buffer_append(buf->next, data, length);
}
buf->data = malloc(length);
strncpy(buf->data, data, length);
buf->length = length;
}
void buffer_append_str(buffer_t* buf, const char* data) {
buffer_append(buf, data, strlen(data));
}
void _buffer_read(buffer_t* buf, char* out) {
int i = 0;
while(buf != NULL) {
strncpy(out + i, buf->data, buf->length);
i += buf->length;
}
}
char* buffer_read(buffer_t* buf, int* plen) {
int length = buffer_length(buf);
if(plen != NULL)
*plen = length;
char* out = malloc(length);
_buffer_read(buf, out);
return out;
}
char* buffer_read_str(buffer_t* buf, int* plen) {
int length = buffer_length(buf);
if(plen != NULL)
*plen = length;
char* out = malloc(length + 1);
out[length] = '\0';
_buffer_read(buf, out);
return out;
}
char* buffer_flush(buffer_t* buf, int* plen) {
char* out = buffer_read(buf, plen);
buffer_clear(buf);
return out;
}
char* buffer_flush_str(buffer_t* buf, int* plen) {
char* out = buffer_read_str(buf, plen);
buffer_clear(buf);
return out;
}
void _buffer_clear(buffer_t* buf, int root) {
if(buf == NULL)
return;
_buffer_clear(buf->next, 0);
free(buf->data);
if(!root)
free(buf);
else {
buf->data = NULL;
buf->next = NULL;
buf->length = 0;
}
}
void buffer_clear(buffer_t* buf) {
_buffer_clear(buf, 1);
}
void buffer_free(buffer_t* buf) {
buffer_clear(buf);
free(buf);
}
/** WEB SOCKET **/
/******************/
wsock_t* wsock_open
(const char* host, const char* path, uint16_t port)
{
char s_port[6];
sprintf(s_port, "%i", port);
int sock;
struct addrinfo hints, *result, *rp;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
if(getaddrinfo(host, s_port, &hints, &result) != 0)
return NULL;
for(rp = result; rp != NULL; rp = rp->ai_next) {
if((sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1)
continue;
if(connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
break;
}
freeaddrinfo(result);
if(rp == NULL)
return NULL;
// todo: randomize wsock key
char s_shake[4096];
sprintf(s_shake,
"GET %s HTTP/1.1\r\n"
"Host: %s:%i\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Key: AQIDBAUGBwgJCgsMDQ4PEC==\r\n"
"Sec-WebSocket-Version: 13\r\n\r\n",
path,
host, port
);
if(send(sock, s_shake, strlen(s_shake), 0) <= 0) {
shutdown(sock, SHUT_RDWR);
return NULL;
}
s_shake[0] = '\0';
struct pollfd pfd;
pfd.fd = sock;
pfd.events = POLLIN;
char* end;
int total = 0;
while((end = strstr(s_shake, "\r\n\r\n")) == NULL) {
if(total + 1 >= sizeof(s_shake)
|| poll(&pfd, 1, 5000) <= 0)
{
shutdown(sock,SHUT_RDWR);
return NULL;
}
total += recv(sock, s_shake + total,
sizeof(s_shake) - total - 1, 0);
s_shake[total] = '\0';
}
shutdown(sock, SHUT_RDWR);
return NULL;
}

View file

@ -1,5 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/poll.h>
#include <netdb.h> #include <netdb.h>
/** DATA BUFFER **/ /** DATA BUFFER **/
@ -14,6 +19,7 @@ typedef struct buffer_t buffer_t;
buffer_t* buffer_create(); buffer_t* buffer_create();
int buffer_is_empty(buffer_t*);
int buffer_length(buffer_t*); int buffer_length(buffer_t*);
void buffer_append(buffer_t*, const char*, int); void buffer_append(buffer_t*, const char*, int);
void buffer_append_str(buffer_t*, const char*); void buffer_append_str(buffer_t*, const char*);
@ -47,15 +53,15 @@ typedef enum {
// WS_FULL_SEND will block on the protocol level, until // WS_FULL_SEND will block on the protocol level, until
// a packet is fully sent or received // a packet is fully sent or received
// for example, WS_BLOCK alone with block until data is // for example, WS_BLOCK alone will block until data is
// available, but will immediately return nothing if the // available, but will immediately return nothing if the
// data received is not a full packet. however, using // data received is not a full packet. however, using
// WS_BLOCK | WS_FULL_RECV will block until data is // WS_BLOCK | WS_FULL_RECV will block until data is
// available, and then until a full websocket packet is // available, and then until a full websocket packet is
// fully constructed, after which the data is returned. // fully received, after which the data is then returned.
// noblock behaves in the same way except the system // WS_NOBLOCK behaves in the same way except the system
// calls will not block, but with WS_FULL_RECV enabled // calls will not block, but with WS_FULL_RECV enabled
// it will then block until a full packet is constructed // it will then block until a full packet is received
// currently WS_FULL_SEND is set to be always enabled // currently WS_FULL_SEND is set to be always enabled
// when the mode is changed because i do not currently // when the mode is changed because i do not currently