From: seantywork Date: Wed, 19 Feb 2025 02:11:02 +0000 (+0900) Subject: working cli X-Git-Url: https://git.feebdaed.xyz/?a=commitdiff_plain;h=75e23cd5316106420894803a1c8527647ce07b06;p=socialize.git working cli --- diff --git a/Makefile b/Makefile index 1816403..0836ffa 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ INCLUDES := -I./include -I./vendor LIBS := -lpthread -lssl -lcrypto -OBJS := core.o +OBJS := ctl.o OBJS += utils.o OBJS += sock.o OBJS += front.o @@ -57,9 +57,9 @@ release: $(OBJS) $(DEP_OBJS) -core.o: +ctl.o: - gcc $(GCC_OBJ_FLAGS) $(INCLUDES) -o core.o src/core.c + gcc $(GCC_OBJ_FLAGS) $(INCLUDES) -o ctl.o src/ctl.c utils.o: @@ -68,11 +68,11 @@ utils.o: sock.o: - gcc $(GCC_OBJ_FLAGS) $(INCLUDES) -o sock.o src/hubsock/core.c + gcc $(GCC_OBJ_FLAGS) $(INCLUDES) -o sock.o src/sock/sock.c front.o: - gcc $(GCC_OBJ_FLAGS) $(INCLUDES) -o front.o src/hubfront/core.c + gcc $(GCC_OBJ_FLAGS) $(INCLUDES) -o front.o src/front/front.c mongoose.o: diff --git a/cmd/cli/main.c b/cmd/cli/main.c index e69de29..b88c30f 100644 --- a/cmd/cli/main.c +++ b/cmd/cli/main.c @@ -0,0 +1,37 @@ +#include "rat-chat/cli/cli.h" +#include "rat-chat/utils.h" + + + +int main(int argc, char **argv){ + + + + if(argc == 1){ + + run_cli(); + + + } else { + + if(strcmp(argv[1], "1") == 0){ + + + run_cli_test(1); + + } else if (strcmp(argv[1], "2") == 0){ + + run_cli_test(2); + + } else { + + printf("wrong argument: %s\n", argv[1]); + + return -1; + + } + + } + + return 0; +} \ No newline at end of file diff --git a/cmd/engine/main.c b/cmd/engine/main.c index 6c3a564..4529fee 100644 --- a/cmd/engine/main.c +++ b/cmd/engine/main.c @@ -1,6 +1,6 @@ -#include "rat-chat/sock/core.h" -#include "rat-chat/front/core.h" +#include "rat-chat/sock/sock.h" +#include "rat-chat/front/front.h" #include "rat-chat/utils.h" FILE* LOGFP; diff --git a/include/rat-chat/cli/cli.h b/include/rat-chat/cli/cli.h new file mode 100644 index 0000000..cba6282 --- /dev/null +++ b/include/rat-chat/cli/cli.h @@ -0,0 +1,20 @@ +#ifndef _FRANK_CLI_H_ +#define _FRANK_CLI_H_ + +#include "rat-chat/core.h" + + + + + +void run_cli(); + + +void run_cli_test(int tc); + + + + + + +#endif diff --git a/include/rat-chat/core.h b/include/rat-chat/core.h index 8a2a095..4c6c1a7 100644 --- a/include/rat-chat/core.h +++ b/include/rat-chat/core.h @@ -138,9 +138,28 @@ #endif #ifndef HUB_CA_CERT -# define HUB_CA_CERT "tls/ca.crt" +# define HUB_CA_CERT "tls/ca.crt.pem" #endif +#ifndef HUB_CA_PRIV +# define HUB_CA_PRIV "tls/ca_priv.pem" +#endif + +#ifndef HUB_CA_PUB +# define HUB_CA_PUB "tls/ca_pub.pem" +#endif + + +#ifndef SUB1_CERT +# define SUB1_CERT "tls/sub1.crt.pem" +#endif + + +#ifndef SUB2_CERT +# define SUB2_CERT "tls/sub2.crt.pem" +#endif + + #define DEFAULT_RANDLEN 64 //#define WAIT 7 @@ -201,75 +220,12 @@ struct settings { }; -int make_socket_non_blocking (int sfd); - -SSL_CTX *create_context(); - -void configure_context(SSL_CTX *ctx); - - -int sig_verify(const char* cert_pem, const char* intermediate_pem); - -int extract_common_name(uint8_t* common_name, const char* cert); - -int idpw_verify(char* idpw); - -int update_chanctx_from_userinfo(char* id, char* pw); - -int update_chanctx_from_sockctx(int fd, char* id); - - - - -int set_sockctx_by_fd(int fd); - -int get_sockctx_by_fd(int fd); - -int set_sockctx_id_by_fd(int fd, char* id); - -int get_sockctx_id_by_fd(int fd, char* id); - -int set_chanctx_by_id(char* id, int create, int fd); - -int get_chanctx_by_id(char* id); - -int set_sockctx_chan_id_by_fd(int fd, int chan_id); - -int get_sockctx_chan_id_by_fd(int fd); - - - -int calloc_chanctx(); - -int free_chanctx(int idx); - -int calloc_sockctx(); - -int free_sockctx(int idx, int memfree); - - - - -int chanctx_write(int type, char* id, int write_len, uint8_t* wbuff); - -int chanctx_read(int type, char* id, int read_len, uint8_t* rbuff); - -int sockctx_write(int fd, int write_len, uint8_t* wbuff); - -int sockctx_read(int fd, int read_len, uint8_t* rbuff); - - - - -void ctx_write_packet(struct HUB_PACKET* hp); - - -void ctx_read_packet(struct HUB_PACKET* hp); - +extern char CA_CERT[MAX_PW_LEN]; +extern char CA_PRIV[MAX_PW_LEN]; -extern char CA_CERT[MAX_PW_LEN]; +extern char CA_PUB[MAX_PW_LEN]; extern int s_sig_num; diff --git a/include/rat-chat/ctl.h b/include/rat-chat/ctl.h new file mode 100644 index 0000000..6df23c3 --- /dev/null +++ b/include/rat-chat/ctl.h @@ -0,0 +1,74 @@ +#ifndef _FRANK_HUB_CTL_H_ +#define _FRANK_HUB_CTL_H_ + +#include "rat-chat/core.h" + +int make_socket_non_blocking (int sfd); + +SSL_CTX *create_context(); + +void configure_context(SSL_CTX *ctx); + + +int sig_verify(const char* cert_pem, const char* intermediate_pem); + +int extract_common_name(uint8_t* common_name, const char* cert); + +int idpw_verify(char* idpw); + +int update_chanctx_from_userinfo(char* id, char* pw); + +int update_chanctx_from_sockctx(int fd, char* id); + + + + +int set_sockctx_by_fd(int fd); + +int get_sockctx_by_fd(int fd); + +int set_sockctx_id_by_fd(int fd, char* id); + +int get_sockctx_id_by_fd(int fd, char* id); + +int set_chanctx_by_id(char* id, int create, int fd); + +int get_chanctx_by_id(char* id); + +int set_sockctx_chan_id_by_fd(int fd, int chan_id); + +int get_sockctx_chan_id_by_fd(int fd); + + + +int calloc_chanctx(); + +int free_chanctx(int idx); + +int calloc_sockctx(); + +int free_sockctx(int idx, int memfree); + + + + +int chanctx_write(int type, char* id, int write_len, uint8_t* wbuff); + +int chanctx_read(int type, char* id, int read_len, uint8_t* rbuff); + +int sockctx_write(int fd, int write_len, uint8_t* wbuff); + +int sockctx_read(int fd, int read_len, uint8_t* rbuff); + + + + +void ctx_write_packet(struct HUB_PACKET* hp); + + +void ctx_read_packet(struct HUB_PACKET* hp); + + + + +#endif \ No newline at end of file diff --git a/include/rat-chat/front/core.h b/include/rat-chat/front/core.h deleted file mode 100644 index bdababe..0000000 --- a/include/rat-chat/front/core.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef _FRANK_HUB_FRONT_H_ -#define _FRANK_HUB_FRONT_H_ - -#include "rat-chat/core.h" - - - - - - -void* front_listen_and_serve(void* varg); - - -void sntp_fn(struct mg_connection *c, int ev, void *ev_data); - -void timer_sntp_fn(void *param); - -void route(struct mg_connection *c, int ev, void *ev_data); - - -void front_handler(struct mg_connection *c, struct mg_ws_message *wm); - - -void handle_healtiness_probe(struct mg_connection *c, struct mg_http_message *hm); - - -int front_authenticate(struct mg_connection* c, struct mg_ws_message *wm, int* initial, char* command, char* data); - -void front_communicate(int chan_idx, char* command, char* data); - - - - - - -#endif \ No newline at end of file diff --git a/include/rat-chat/front/front.h b/include/rat-chat/front/front.h new file mode 100644 index 0000000..bdababe --- /dev/null +++ b/include/rat-chat/front/front.h @@ -0,0 +1,36 @@ +#ifndef _FRANK_HUB_FRONT_H_ +#define _FRANK_HUB_FRONT_H_ + +#include "rat-chat/core.h" + + + + + + +void* front_listen_and_serve(void* varg); + + +void sntp_fn(struct mg_connection *c, int ev, void *ev_data); + +void timer_sntp_fn(void *param); + +void route(struct mg_connection *c, int ev, void *ev_data); + + +void front_handler(struct mg_connection *c, struct mg_ws_message *wm); + + +void handle_healtiness_probe(struct mg_connection *c, struct mg_http_message *hm); + + +int front_authenticate(struct mg_connection* c, struct mg_ws_message *wm, int* initial, char* command, char* data); + +void front_communicate(int chan_idx, char* command, char* data); + + + + + + +#endif \ No newline at end of file diff --git a/include/rat-chat/sock/core.h b/include/rat-chat/sock/core.h deleted file mode 100644 index 0242b59..0000000 --- a/include/rat-chat/sock/core.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _FRANK_HUB_SOCK_H_ -#define _FRANK_HUB_SOCK_H_ - - - -#include "rat-chat/core.h" - - - -void sock_listen_and_serve(void* varg); - - -void sock_handle_conn(); - - -void sock_handle_client(int cfd); - -void sock_authenticate(int cfd); - -void sock_register(int cfd); - -void sock_communicate(int chan_idx, int sock_idx); - -#endif \ No newline at end of file diff --git a/include/rat-chat/sock/sock.h b/include/rat-chat/sock/sock.h new file mode 100644 index 0000000..0242b59 --- /dev/null +++ b/include/rat-chat/sock/sock.h @@ -0,0 +1,24 @@ +#ifndef _FRANK_HUB_SOCK_H_ +#define _FRANK_HUB_SOCK_H_ + + + +#include "rat-chat/core.h" + + + +void sock_listen_and_serve(void* varg); + + +void sock_handle_conn(); + + +void sock_handle_client(int cfd); + +void sock_authenticate(int cfd); + +void sock_register(int cfd); + +void sock_communicate(int chan_idx, int sock_idx); + +#endif \ No newline at end of file diff --git a/src/cli/cli.c b/src/cli/cli.c new file mode 100644 index 0000000..95b4af8 --- /dev/null +++ b/src/cli/cli.c @@ -0,0 +1,24 @@ +#include "rat-chat/cli/cli.h" +#include "rat-chat/utils.h" + + + + +void run_cli(){ + + + +} + + +void run_cli_test(int tc){ + + + + + + +} + + + diff --git a/src/core.c b/src/core.c deleted file mode 100644 index 400fcab..0000000 --- a/src/core.c +++ /dev/null @@ -1,1048 +0,0 @@ -#include "rat-chat/core.h" - - -struct CHANNEL_CONTEXT CHAN_CTX[MAX_CONN]; - -struct SOCK_CONTEXT SOCK_CTX[MAX_CONN]; - - - -int make_socket_non_blocking (int sfd){ - int flags, s; - - flags = fcntl (sfd, F_GETFL, 0); - if (flags == -1) - { - perror ("fcntl get"); - return -1; - } - - flags |= O_NONBLOCK; - s = fcntl (sfd, F_SETFL, flags); - if (s == -1) - { - perror ("fcntl set"); - return -2; - } - - return 0; -} - - -SSL_CTX *create_context(){ - - const SSL_METHOD *method; - SSL_CTX *ctx; - - method = TLS_server_method(); - - ctx = SSL_CTX_new(method); - if (!ctx) { - perror("Unable to create SSL context"); - ERR_print_errors_fp(stderr); - exit(EXIT_FAILURE); - } - - return ctx; -} - -void configure_context(SSL_CTX *ctx){ - - if (SSL_CTX_use_certificate_file(ctx, SERVER_CERT, SSL_FILETYPE_PEM) <= 0) { - ERR_print_errors_fp(stderr); - exit(EXIT_FAILURE); - } - - if (SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY, SSL_FILETYPE_PEM) <= 0 ) { - ERR_print_errors_fp(stderr); - exit(EXIT_FAILURE); - } -} - -int sig_verify(const char* cert_pem, const char* intermediate_pem){ - - BIO *b = BIO_new(BIO_s_mem()); - BIO_puts(b, intermediate_pem); - X509 * issuer = PEM_read_bio_X509(b, NULL, NULL, NULL); - EVP_PKEY *signing_key=X509_get_pubkey(issuer); - - BIO *c = BIO_new(BIO_s_mem()); - BIO_puts(c, cert_pem); - X509 * x509 = PEM_read_bio_X509(c, NULL, NULL, NULL); - - int result = X509_verify(x509, signing_key); - - EVP_PKEY_free(signing_key); - BIO_free(b); - BIO_free(c); - X509_free(x509); - X509_free(issuer); - - return result; -} - -int extract_common_name(uint8_t* common_name, const char* cert) { - - BIO *b = BIO_new(BIO_s_mem()); - BIO_puts(b, cert); - X509 * x509 = PEM_read_bio_X509(b, NULL, NULL, NULL); - - int ret_cn = -1; - - int common_name_loc = X509_NAME_get_index_by_NID(X509_get_subject_name(x509), NID_commonName, -1); - if (common_name_loc < 0) { - BIO_free(b); - X509_free(x509); - return ret_cn; - } - - X509_NAME_ENTRY * common_name_entry = X509_NAME_get_entry(X509_get_subject_name(x509), common_name_loc); - if (common_name_entry == NULL) { - BIO_free(b); - X509_free(x509); - return ret_cn; - } - - ASN1_STRING * common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); - if (common_name_asn1 == NULL) { - BIO_free(b); - X509_free(x509); - return ret_cn; - } - - char const * common_name_str = (char const *) ASN1_STRING_get0_data(common_name_asn1); - - if (ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) { - BIO_free(b); - X509_free(x509); - return ret_cn; - } - - strcpy(common_name, common_name_str); - - ret_cn = 1; - - BIO_free(b); - X509_free(x509); - - return ret_cn; -} - - -int idpw_verify(char* idpw){ - - int verify = -1; - - char* token; - - char* delim = ":"; - - uint8_t id[MAX_ID_LEN] = {0}; - uint8_t pw[MAX_PW_LEN] = {0}; - - token = strtok(idpw, delim); - - int idx = 0; - - while( token != NULL ) { - - if(idx > 1) { - break; - } - - if(idx == 0){ - - strncpy(id, token, MAX_ID_LEN); - - } else { - - strncpy(pw, token, MAX_PW_LEN); - - } - - token = strtok(NULL, delim); - - idx += 1; - } - - if(idx != 2){ - return -1; - } - - int chan_idx = get_chanctx_by_id(id); - - if(chan_idx < 0){ - - return -2; - - } - - if(strncmp(CHAN_CTX[chan_idx].pw, pw, MAX_PW_LEN) != 0){ - - return -3; - - } - - int verified_idx = chan_idx; - - - return verified_idx; - -} - -int update_chanctx_from_userinfo(char* id, char* pw){ - - int ret_idx = -1; - - int chan_idx = get_chanctx_by_id(id); - - if(chan_idx < 0){ - - - ret_idx = calloc_chanctx(); - - if(ret_idx < 0){ - - printf("id %s failed to calloc chanctx: max conn\n", id); - - return -2; - - } - - - strcpy(CHAN_CTX[ret_idx].id, id); - strcpy(CHAN_CTX[ret_idx].pw, pw); - - chan_idx = ret_idx; - - printf("id %s added to chanctx from userinfo\n", id); - - - } else { - - - strcpy(CHAN_CTX[chan_idx].pw, pw); - - - printf("id %s modified for existing chanctx from userinfo\n", id); - - - } - - - - ret_idx = chan_idx; - - - return ret_idx; - -} - - -int update_chanctx_from_sockctx(int fd, char* id){ - - - int ret_idx = -1; - - - int sock_idx = get_sockctx_by_fd(fd); - - if(sock_idx < 0){ - - printf("no sock fd associated with: %d\n",fd); - - return -1; - } - - int chan_idx = get_chanctx_by_id(id); - - - if(chan_idx < 0){ - - ret_idx = calloc_chanctx(); - - if(ret_idx < 0){ - - printf("sock fd %d failed to calloc chanctx: max conn\n", fd); - - return -2; - - } - - chan_idx = ret_idx; - - CHAN_CTX[chan_idx].sockfd = SOCK_CTX[sock_idx].sockfd; - CHAN_CTX[chan_idx].ssl = SOCK_CTX[sock_idx].ssl; - CHAN_CTX[chan_idx].ctx = SOCK_CTX[sock_idx].ctx; - - free_sockctx(sock_idx, 0); - - strcpy(CHAN_CTX[chan_idx].id, id); - - printf("id %s added to chanctx %d from sock\n", id, chan_idx); - - } else { - - - CHAN_CTX[chan_idx].sockfd = SOCK_CTX[sock_idx].sockfd; - CHAN_CTX[chan_idx].ssl = SOCK_CTX[sock_idx].ssl; - CHAN_CTX[chan_idx].ctx = SOCK_CTX[sock_idx].ctx; - - free_sockctx(sock_idx, 0); - - printf("id %s modified for existing chanctx from sock\n", id); - - - } - - ret_idx = chan_idx; - - return ret_idx; - -} - - - - - - -int set_sockctx_by_fd(int fd){ - - - int new_idx = calloc_sockctx(); - - if(new_idx < 0){ - - - return -1; - - } - - SOCK_CTX[new_idx].sockfd = fd; - - return new_idx; -} - - - - -int get_sockctx_by_fd(int fd){ - - - for(int i = 0; i < MAX_CONN; i++){ - - - if(SOCK_CTX[i].sockfd == fd){ - - return i; - - } - - - } - - - - return -1; -} - - -int set_sockctx_id_by_fd(int fd, char* id){ - - int idx = get_sockctx_by_fd(fd); - - if(idx < 0){ - - return -1; - } - - memcpy(SOCK_CTX[idx].id, id, MAX_ID_LEN); - - return 0; -} - -int get_sockctx_id_by_fd(int fd, char* id){ - - - - int idx = get_sockctx_by_fd(fd); - - if(idx < 0){ - - return -1; - } - - memcpy(id, SOCK_CTX[idx].id, MAX_ID_LEN); - - return 0; - -} - - - -int set_chanctx_by_id(char* id, int create, int fd){ - - int idx = get_chanctx_by_id(id); - - if(create == 1){ - - if(idx < 0){ - - idx = calloc_chanctx(); - - memcpy(CHAN_CTX[idx].id, id, MAX_ID_LEN); - - CHAN_CTX[idx].fds[CHAN_CTX[idx].fd_ptr] = fd; - - CHAN_CTX[idx].fd_ptr += 1; - - } else { - - return -1; - } - - - } else { - - - if(idx < 0){ - - return -2; - - } else { - - CHAN_CTX[idx].fds[CHAN_CTX[idx].fd_ptr] = fd; - CHAN_CTX[idx].fd_ptr += 1; - } - - - } - - - return idx; - - -} - - -int get_chanctx_by_id(char* id){ - - - for(int i = 0; i < MAX_CONN; i++){ - - if(strcmp(CHAN_CTX[i].id, id) == 0){ - - return i; - - } - - } - - - return -1; -} - - - -int set_sockctx_chan_id_by_fd(int fd, int chan_id){ - - - int idx = get_sockctx_by_fd(fd); - - if(idx < 0){ - - return -1; - } - - SOCK_CTX[idx].chan_idx = chan_id; - - return 0; - -} - - - - -int get_sockctx_chan_id_by_fd(int fd){ - - - int idx = get_sockctx_by_fd(fd); - - if(idx < 0){ - - return -1; - } - - return SOCK_CTX[idx].chan_idx; - -} - - - -int calloc_chanctx(){ - - for(int i = 0; i < MAX_CONN; i++){ - - - if(CHAN_CTX[i].allocated == 0){ - - CHAN_CTX[i].allocated = 1; - - CHAN_CTX[i].sockfd = 0; - CHAN_CTX[i].frontfd = 0; - - memset(CHAN_CTX[i].id, 0, MAX_ID_LEN * sizeof(char)); - memset(CHAN_CTX[i].pw, 0, MAX_PW_LEN * sizeof(char)); - - CHAN_CTX[i].ssl = NULL; - CHAN_CTX[i].ctx = NULL; - - - return i; - - } - - } - - - return -1; -} - - -int free_chanctx(int idx){ - - if(idx >= MAX_CONN){ - - return -10; - } - - if(CHAN_CTX[idx].allocated != 1){ - - return -1; - - } - - if (CHAN_CTX[idx].ssl != NULL){ - - SSL_shutdown(CHAN_CTX[idx].ssl); - SSL_free(CHAN_CTX[idx].ssl); - - } - - if (CHAN_CTX[idx].ctx != NULL){ - - SSL_CTX_free(CHAN_CTX[idx].ctx); - - } - - CHAN_CTX[idx].sockfd = 0; - CHAN_CTX[idx].frontfd = 0; - - - memset(CHAN_CTX[idx].id, 0, MAX_ID_LEN * sizeof(char)); - memset(CHAN_CTX[idx].pw, 0, MAX_PW_LEN * sizeof(char)); - - CHAN_CTX[idx].ssl = NULL; - CHAN_CTX[idx].ctx = NULL; - - CHAN_CTX[idx].allocated = 0; - - return 0; -} - - -int calloc_sockctx(){ - - for(int i = 0; i < MAX_CONN; i++){ - - if(SOCK_CTX[i].allocated == 0){ - - SOCK_CTX[i].ctx = NULL; - SOCK_CTX[i].ssl = NULL; - SOCK_CTX[i].sockfd = 0; - SOCK_CTX[i].chan_idx = -1; - - SOCK_CTX[i].allocated = 1; - - return i; - - } - - - } - - - return -1; -} - - - -int free_sockctx(int idx, int memfree){ - - - if (idx >= MAX_CONN){ - return -10; - } - - if(SOCK_CTX[idx].allocated != 1){ - return -1; - } - - if(memfree == 1){ - - SSL_shutdown(SOCK_CTX[idx].ssl); - SSL_free(SOCK_CTX[idx].ssl); - SSL_CTX_free(SOCK_CTX[idx].ctx); - - } else { - - SOCK_CTX[idx].ssl = NULL; - SOCK_CTX[idx].ctx = NULL; - - } - - SOCK_CTX[idx].sockfd = 0; - SOCK_CTX[idx].allocated = 0; - - - return 0; -} - - -int chanctx_write(int type, char* id, int write_len, uint8_t* wbuff){ - - if(type == ISSOCK){ - - int valwrite = 0; - - int chan_idx = 0; - - chan_idx = get_chanctx_by_id(id); - - if(chan_idx < 0){ - - printf("write: no such id: %s\n", id); - - return -1; - } - - - SSL* sslfd = CHAN_CTX[chan_idx].ssl; - - - valwrite = SSL_write(sslfd, wbuff, write_len); - - - if (valwrite <= 0){ - - printf("write: client gone: %d\n", valwrite); - - return -2; - - } - - return valwrite; - - - } - - - printf("invalid chanctx write type: %d\n", type); - - return -100; - - -} - -int chanctx_read(int type, char* id, int read_len, uint8_t* rbuff){ - - if(type == ISSOCK){ - - int valread = 0; - - int chan_idx = 0; - - int ms_until_deadline = 0; - - chan_idx = get_chanctx_by_id(id); - - if(chan_idx < 0){ - - printf("read: no such id: %s\n", id); - - return -1; - } - - - SSL* sslfd = CHAN_CTX[chan_idx].ssl; - - uint8_t* rbuff_tmp = (uint8_t*)malloc(read_len * sizeof(uint8_t)); - - memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); - - int valread_tmp = 0; - - struct timespec rnow; - - clock_gettime(CLOCK_MONOTONIC_RAW, &rnow); - - struct timespec rdeadline; - - while(valread < read_len){ - - clock_gettime(CLOCK_MONOTONIC_RAW, &rdeadline); - - ms_until_deadline = ((rdeadline.tv_sec - rnow.tv_sec) * 1000 + (rdeadline.tv_nsec - rnow.tv_nsec) / 1000000); - - if(ms_until_deadline > HUB_TIMEOUT_MS){ - - printf("time limit exceeded\n"); - - free(rbuff_tmp); - - return -10; - } - - valread_tmp = SSL_read(sslfd, (void*)rbuff_tmp, read_len); - - if(valread_tmp <= 0){ - - if(errno == EAGAIN){ - - memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); - - valread_tmp = 0; - - continue; - } - - printf("read: client gone: %d\n", valread); - - free(rbuff_tmp); - - return -2; - } - - for(int i = 0 ; i < valread_tmp; i++){ - - int idx = valread + i; - - rbuff[idx] = rbuff_tmp[i]; - - } - - valread += valread_tmp; - - memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); - - valread_tmp = 0; - - } - - - free(rbuff_tmp); - - return valread; - - - } - - - printf("invalid chanctx read type: %d\n", type); - - return -100; - - -} - - -int sockctx_write(int fd, int write_len, uint8_t* wbuff){ - - - int valwrite = 0; - - int sock_idx = 0; - - sock_idx = get_sockctx_by_fd(fd); - - if(sock_idx < 0){ - - printf("write: no such fd: %d\n", fd); - - return -1; - } - - SSL* sslfd = SOCK_CTX[sock_idx].ssl; - - - valwrite = SSL_write(sslfd, (void*)wbuff, write_len); - - if (valwrite <= 0){ - - printf("write: client gone: %d\n", valwrite); - - return -2; - - } - - return valwrite; - - - -} - -int sockctx_read(int fd, int read_len, uint8_t* rbuff){ - - - - int valread = 0; - - int sock_idx = 0; - - int ms_until_deadline = 0; - - sock_idx = get_sockctx_by_fd(fd); - - if(sock_idx < 0){ - - printf("read: no such fd: %d\n", fd); - - return -1; - } - - - SSL* sslfd = SOCK_CTX[sock_idx].ssl; - - uint8_t* rbuff_tmp = (uint8_t*)malloc(read_len * sizeof(uint8_t)); - - memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); - - int valread_tmp = 0; - - struct timespec rnow; - - clock_gettime(CLOCK_MONOTONIC_RAW, &rnow); - - struct timespec rdeadline; - - while(valread < read_len){ - - clock_gettime(CLOCK_MONOTONIC_RAW, &rdeadline); - - ms_until_deadline = ((rdeadline.tv_sec - rnow.tv_sec) * 1000 + (rdeadline.tv_nsec - rnow.tv_nsec) / 1000000); - - if(ms_until_deadline > HUB_TIMEOUT_MS){ - - printf("time limit exceeded\n"); - - free(rbuff_tmp); - - return -10; - } - - valread_tmp = SSL_read(sslfd, (void*)rbuff_tmp, read_len); - - if(valread_tmp <= 0){ - - if(errno == EAGAIN){ - - memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); - - valread_tmp = 0; - - continue; - } - - printf("read: client gone: %d\n", valread); - - free(rbuff_tmp); - - return -2; - } - - for(int i = 0 ; i < valread_tmp; i++){ - - int idx = valread + i; - - rbuff[idx] = rbuff_tmp[i]; - - } - - valread += valread_tmp; - - memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); - - valread_tmp = 0; - - } - - free(rbuff_tmp); - - return valread; - - -} - - - - - - - -void ctx_write_packet(struct HUB_PACKET* hp){ - - int valwrite = 0; - - - if(hp->ctx_type == ISSOCK){ - - valwrite = sockctx_write(hp->fd, HUB_HEADER_BYTELEN, hp->header); - - if(valwrite <= 0){ - - printf("packet send header failed\n"); - - hp->flag = valwrite; - - return; - - } - - uint8_t body_len_byte[HUB_BODY_BYTELEN] = {0}; - - uint64_t body_len_new = 0; - - body_len_new = htonll(hp->body_len); - - memcpy(body_len_byte, &body_len_new, HUB_BODY_BYTELEN); - - valwrite = sockctx_write(hp->fd, HUB_BODY_BYTELEN, body_len_byte); - - if(valwrite <= 0){ - - printf("packet send body len failed\n"); - - hp->flag = valwrite; - - return; - - } - - valwrite = sockctx_write(hp->fd, hp->body_len, hp->wbuff); - - if(valwrite <= 0){ - - printf("packet send buff failed\n"); - - hp->flag = valwrite; - - return; - - } - - hp->flag = valwrite; - - return; - - - } - - - printf("invalid ctx write packet type: %d\n", hp->ctx_type); - - hp->flag = valwrite; - - - return; - -} - - -void ctx_read_packet(struct HUB_PACKET* hp){ - - int valread = 0; - - if(hp->ctx_type == ISSOCK){ - - valread = sockctx_read(hp->fd, HUB_HEADER_BYTELEN, hp->header); - - if(valread <= 0){ - - printf("packet recv header failed\n"); - - hp->flag = valread; - - return; - - } - - uint8_t body_len_byte[HUB_BODY_BYTELEN] = {0}; - - uint64_t body_len = 0; - - valread = sockctx_read(hp->fd, HUB_BODY_BYTELEN, body_len_byte); - - if(valread <= 0){ - - printf("packet recv body len failed\n"); - - hp->flag = valread; - - return; - - } - - memcpy(&body_len, body_len_byte, HUB_BODY_BYTELEN); - - body_len = ntohll(body_len); - - if(body_len > HUB_BODY_BYTEMAX){ - - printf("packet body len too long \n"); - - hp->flag = -10; - - return; - } - - hp->body_len = body_len; - - hp->rbuff = (uint8_t*)malloc(hp->body_len * sizeof(uint8_t)); - - memset(hp->rbuff, 0, hp->body_len * sizeof(uint8_t)); - - valread = sockctx_read(hp->fd, hp->body_len, hp->rbuff); - - if(valread <= 0){ - - printf("packet recv body failed\n"); - - free(hp->rbuff); - - hp->flag = valread; - - return; - - } - - hp->flag = valread; - - return; - - - } - - - - - printf("invalid ctx read packet type: %d\n", hp->ctx_type); - - hp->flag = valread; - - return; -} - - - - - diff --git a/src/ctl.c b/src/ctl.c new file mode 100644 index 0000000..380da9d --- /dev/null +++ b/src/ctl.c @@ -0,0 +1,1048 @@ +#include "rat-chat/ctl.h" + + +struct CHANNEL_CONTEXT CHAN_CTX[MAX_CONN]; + +struct SOCK_CONTEXT SOCK_CTX[MAX_CONN]; + + + +int make_socket_non_blocking (int sfd){ + int flags, s; + + flags = fcntl (sfd, F_GETFL, 0); + if (flags == -1) + { + perror ("fcntl get"); + return -1; + } + + flags |= O_NONBLOCK; + s = fcntl (sfd, F_SETFL, flags); + if (s == -1) + { + perror ("fcntl set"); + return -2; + } + + return 0; +} + + +SSL_CTX *create_context(){ + + const SSL_METHOD *method; + SSL_CTX *ctx; + + method = TLS_server_method(); + + ctx = SSL_CTX_new(method); + if (!ctx) { + perror("Unable to create SSL context"); + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } + + return ctx; +} + +void configure_context(SSL_CTX *ctx){ + + if (SSL_CTX_use_certificate_file(ctx, SERVER_CERT, SSL_FILETYPE_PEM) <= 0) { + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } + + if (SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY, SSL_FILETYPE_PEM) <= 0 ) { + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } +} + +int sig_verify(const char* cert_pem, const char* intermediate_pem){ + + BIO *b = BIO_new(BIO_s_mem()); + BIO_puts(b, intermediate_pem); + X509 * issuer = PEM_read_bio_X509(b, NULL, NULL, NULL); + EVP_PKEY *signing_key=X509_get_pubkey(issuer); + + BIO *c = BIO_new(BIO_s_mem()); + BIO_puts(c, cert_pem); + X509 * x509 = PEM_read_bio_X509(c, NULL, NULL, NULL); + + int result = X509_verify(x509, signing_key); + + EVP_PKEY_free(signing_key); + BIO_free(b); + BIO_free(c); + X509_free(x509); + X509_free(issuer); + + return result; +} + +int extract_common_name(uint8_t* common_name, const char* cert) { + + BIO *b = BIO_new(BIO_s_mem()); + BIO_puts(b, cert); + X509 * x509 = PEM_read_bio_X509(b, NULL, NULL, NULL); + + int ret_cn = -1; + + int common_name_loc = X509_NAME_get_index_by_NID(X509_get_subject_name(x509), NID_commonName, -1); + if (common_name_loc < 0) { + BIO_free(b); + X509_free(x509); + return ret_cn; + } + + X509_NAME_ENTRY * common_name_entry = X509_NAME_get_entry(X509_get_subject_name(x509), common_name_loc); + if (common_name_entry == NULL) { + BIO_free(b); + X509_free(x509); + return ret_cn; + } + + ASN1_STRING * common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); + if (common_name_asn1 == NULL) { + BIO_free(b); + X509_free(x509); + return ret_cn; + } + + char const * common_name_str = (char const *) ASN1_STRING_get0_data(common_name_asn1); + + if (ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) { + BIO_free(b); + X509_free(x509); + return ret_cn; + } + + strcpy(common_name, common_name_str); + + ret_cn = 1; + + BIO_free(b); + X509_free(x509); + + return ret_cn; +} + + +int idpw_verify(char* idpw){ + + int verify = -1; + + char* token; + + char* delim = ":"; + + uint8_t id[MAX_ID_LEN] = {0}; + uint8_t pw[MAX_PW_LEN] = {0}; + + token = strtok(idpw, delim); + + int idx = 0; + + while( token != NULL ) { + + if(idx > 1) { + break; + } + + if(idx == 0){ + + strncpy(id, token, MAX_ID_LEN); + + } else { + + strncpy(pw, token, MAX_PW_LEN); + + } + + token = strtok(NULL, delim); + + idx += 1; + } + + if(idx != 2){ + return -1; + } + + int chan_idx = get_chanctx_by_id(id); + + if(chan_idx < 0){ + + return -2; + + } + + if(strncmp(CHAN_CTX[chan_idx].pw, pw, MAX_PW_LEN) != 0){ + + return -3; + + } + + int verified_idx = chan_idx; + + + return verified_idx; + +} + +int update_chanctx_from_userinfo(char* id, char* pw){ + + int ret_idx = -1; + + int chan_idx = get_chanctx_by_id(id); + + if(chan_idx < 0){ + + + ret_idx = calloc_chanctx(); + + if(ret_idx < 0){ + + printf("id %s failed to calloc chanctx: max conn\n", id); + + return -2; + + } + + + strcpy(CHAN_CTX[ret_idx].id, id); + strcpy(CHAN_CTX[ret_idx].pw, pw); + + chan_idx = ret_idx; + + printf("id %s added to chanctx from userinfo\n", id); + + + } else { + + + strcpy(CHAN_CTX[chan_idx].pw, pw); + + + printf("id %s modified for existing chanctx from userinfo\n", id); + + + } + + + + ret_idx = chan_idx; + + + return ret_idx; + +} + + +int update_chanctx_from_sockctx(int fd, char* id){ + + + int ret_idx = -1; + + + int sock_idx = get_sockctx_by_fd(fd); + + if(sock_idx < 0){ + + printf("no sock fd associated with: %d\n",fd); + + return -1; + } + + int chan_idx = get_chanctx_by_id(id); + + + if(chan_idx < 0){ + + ret_idx = calloc_chanctx(); + + if(ret_idx < 0){ + + printf("sock fd %d failed to calloc chanctx: max conn\n", fd); + + return -2; + + } + + chan_idx = ret_idx; + + CHAN_CTX[chan_idx].sockfd = SOCK_CTX[sock_idx].sockfd; + CHAN_CTX[chan_idx].ssl = SOCK_CTX[sock_idx].ssl; + CHAN_CTX[chan_idx].ctx = SOCK_CTX[sock_idx].ctx; + + free_sockctx(sock_idx, 0); + + strcpy(CHAN_CTX[chan_idx].id, id); + + printf("id %s added to chanctx %d from sock\n", id, chan_idx); + + } else { + + + CHAN_CTX[chan_idx].sockfd = SOCK_CTX[sock_idx].sockfd; + CHAN_CTX[chan_idx].ssl = SOCK_CTX[sock_idx].ssl; + CHAN_CTX[chan_idx].ctx = SOCK_CTX[sock_idx].ctx; + + free_sockctx(sock_idx, 0); + + printf("id %s modified for existing chanctx from sock\n", id); + + + } + + ret_idx = chan_idx; + + return ret_idx; + +} + + + + + + +int set_sockctx_by_fd(int fd){ + + + int new_idx = calloc_sockctx(); + + if(new_idx < 0){ + + + return -1; + + } + + SOCK_CTX[new_idx].sockfd = fd; + + return new_idx; +} + + + + +int get_sockctx_by_fd(int fd){ + + + for(int i = 0; i < MAX_CONN; i++){ + + + if(SOCK_CTX[i].sockfd == fd){ + + return i; + + } + + + } + + + + return -1; +} + + +int set_sockctx_id_by_fd(int fd, char* id){ + + int idx = get_sockctx_by_fd(fd); + + if(idx < 0){ + + return -1; + } + + memcpy(SOCK_CTX[idx].id, id, MAX_ID_LEN); + + return 0; +} + +int get_sockctx_id_by_fd(int fd, char* id){ + + + + int idx = get_sockctx_by_fd(fd); + + if(idx < 0){ + + return -1; + } + + memcpy(id, SOCK_CTX[idx].id, MAX_ID_LEN); + + return 0; + +} + + + +int set_chanctx_by_id(char* id, int create, int fd){ + + int idx = get_chanctx_by_id(id); + + if(create == 1){ + + if(idx < 0){ + + idx = calloc_chanctx(); + + memcpy(CHAN_CTX[idx].id, id, MAX_ID_LEN); + + CHAN_CTX[idx].fds[CHAN_CTX[idx].fd_ptr] = fd; + + CHAN_CTX[idx].fd_ptr += 1; + + } else { + + return -1; + } + + + } else { + + + if(idx < 0){ + + return -2; + + } else { + + CHAN_CTX[idx].fds[CHAN_CTX[idx].fd_ptr] = fd; + CHAN_CTX[idx].fd_ptr += 1; + } + + + } + + + return idx; + + +} + + +int get_chanctx_by_id(char* id){ + + + for(int i = 0; i < MAX_CONN; i++){ + + if(strcmp(CHAN_CTX[i].id, id) == 0){ + + return i; + + } + + } + + + return -1; +} + + + +int set_sockctx_chan_id_by_fd(int fd, int chan_id){ + + + int idx = get_sockctx_by_fd(fd); + + if(idx < 0){ + + return -1; + } + + SOCK_CTX[idx].chan_idx = chan_id; + + return 0; + +} + + + + +int get_sockctx_chan_id_by_fd(int fd){ + + + int idx = get_sockctx_by_fd(fd); + + if(idx < 0){ + + return -1; + } + + return SOCK_CTX[idx].chan_idx; + +} + + + +int calloc_chanctx(){ + + for(int i = 0; i < MAX_CONN; i++){ + + + if(CHAN_CTX[i].allocated == 0){ + + CHAN_CTX[i].allocated = 1; + + CHAN_CTX[i].sockfd = 0; + CHAN_CTX[i].frontfd = 0; + + memset(CHAN_CTX[i].id, 0, MAX_ID_LEN * sizeof(char)); + memset(CHAN_CTX[i].pw, 0, MAX_PW_LEN * sizeof(char)); + + CHAN_CTX[i].ssl = NULL; + CHAN_CTX[i].ctx = NULL; + + + return i; + + } + + } + + + return -1; +} + + +int free_chanctx(int idx){ + + if(idx >= MAX_CONN){ + + return -10; + } + + if(CHAN_CTX[idx].allocated != 1){ + + return -1; + + } + + if (CHAN_CTX[idx].ssl != NULL){ + + SSL_shutdown(CHAN_CTX[idx].ssl); + SSL_free(CHAN_CTX[idx].ssl); + + } + + if (CHAN_CTX[idx].ctx != NULL){ + + SSL_CTX_free(CHAN_CTX[idx].ctx); + + } + + CHAN_CTX[idx].sockfd = 0; + CHAN_CTX[idx].frontfd = 0; + + + memset(CHAN_CTX[idx].id, 0, MAX_ID_LEN * sizeof(char)); + memset(CHAN_CTX[idx].pw, 0, MAX_PW_LEN * sizeof(char)); + + CHAN_CTX[idx].ssl = NULL; + CHAN_CTX[idx].ctx = NULL; + + CHAN_CTX[idx].allocated = 0; + + return 0; +} + + +int calloc_sockctx(){ + + for(int i = 0; i < MAX_CONN; i++){ + + if(SOCK_CTX[i].allocated == 0){ + + SOCK_CTX[i].ctx = NULL; + SOCK_CTX[i].ssl = NULL; + SOCK_CTX[i].sockfd = 0; + SOCK_CTX[i].chan_idx = -1; + + SOCK_CTX[i].allocated = 1; + + return i; + + } + + + } + + + return -1; +} + + + +int free_sockctx(int idx, int memfree){ + + + if (idx >= MAX_CONN){ + return -10; + } + + if(SOCK_CTX[idx].allocated != 1){ + return -1; + } + + if(memfree == 1){ + + SSL_shutdown(SOCK_CTX[idx].ssl); + SSL_free(SOCK_CTX[idx].ssl); + SSL_CTX_free(SOCK_CTX[idx].ctx); + + } else { + + SOCK_CTX[idx].ssl = NULL; + SOCK_CTX[idx].ctx = NULL; + + } + + SOCK_CTX[idx].sockfd = 0; + SOCK_CTX[idx].allocated = 0; + + + return 0; +} + + +int chanctx_write(int type, char* id, int write_len, uint8_t* wbuff){ + + if(type == ISSOCK){ + + int valwrite = 0; + + int chan_idx = 0; + + chan_idx = get_chanctx_by_id(id); + + if(chan_idx < 0){ + + printf("write: no such id: %s\n", id); + + return -1; + } + + + SSL* sslfd = CHAN_CTX[chan_idx].ssl; + + + valwrite = SSL_write(sslfd, wbuff, write_len); + + + if (valwrite <= 0){ + + printf("write: client gone: %d\n", valwrite); + + return -2; + + } + + return valwrite; + + + } + + + printf("invalid chanctx write type: %d\n", type); + + return -100; + + +} + +int chanctx_read(int type, char* id, int read_len, uint8_t* rbuff){ + + if(type == ISSOCK){ + + int valread = 0; + + int chan_idx = 0; + + int ms_until_deadline = 0; + + chan_idx = get_chanctx_by_id(id); + + if(chan_idx < 0){ + + printf("read: no such id: %s\n", id); + + return -1; + } + + + SSL* sslfd = CHAN_CTX[chan_idx].ssl; + + uint8_t* rbuff_tmp = (uint8_t*)malloc(read_len * sizeof(uint8_t)); + + memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); + + int valread_tmp = 0; + + struct timespec rnow; + + clock_gettime(CLOCK_MONOTONIC_RAW, &rnow); + + struct timespec rdeadline; + + while(valread < read_len){ + + clock_gettime(CLOCK_MONOTONIC_RAW, &rdeadline); + + ms_until_deadline = ((rdeadline.tv_sec - rnow.tv_sec) * 1000 + (rdeadline.tv_nsec - rnow.tv_nsec) / 1000000); + + if(ms_until_deadline > HUB_TIMEOUT_MS){ + + printf("time limit exceeded\n"); + + free(rbuff_tmp); + + return -10; + } + + valread_tmp = SSL_read(sslfd, (void*)rbuff_tmp, read_len); + + if(valread_tmp <= 0){ + + if(errno == EAGAIN){ + + memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); + + valread_tmp = 0; + + continue; + } + + printf("read: client gone: %d\n", valread); + + free(rbuff_tmp); + + return -2; + } + + for(int i = 0 ; i < valread_tmp; i++){ + + int idx = valread + i; + + rbuff[idx] = rbuff_tmp[i]; + + } + + valread += valread_tmp; + + memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); + + valread_tmp = 0; + + } + + + free(rbuff_tmp); + + return valread; + + + } + + + printf("invalid chanctx read type: %d\n", type); + + return -100; + + +} + + +int sockctx_write(int fd, int write_len, uint8_t* wbuff){ + + + int valwrite = 0; + + int sock_idx = 0; + + sock_idx = get_sockctx_by_fd(fd); + + if(sock_idx < 0){ + + printf("write: no such fd: %d\n", fd); + + return -1; + } + + SSL* sslfd = SOCK_CTX[sock_idx].ssl; + + + valwrite = SSL_write(sslfd, (void*)wbuff, write_len); + + if (valwrite <= 0){ + + printf("write: client gone: %d\n", valwrite); + + return -2; + + } + + return valwrite; + + + +} + +int sockctx_read(int fd, int read_len, uint8_t* rbuff){ + + + + int valread = 0; + + int sock_idx = 0; + + int ms_until_deadline = 0; + + sock_idx = get_sockctx_by_fd(fd); + + if(sock_idx < 0){ + + printf("read: no such fd: %d\n", fd); + + return -1; + } + + + SSL* sslfd = SOCK_CTX[sock_idx].ssl; + + uint8_t* rbuff_tmp = (uint8_t*)malloc(read_len * sizeof(uint8_t)); + + memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); + + int valread_tmp = 0; + + struct timespec rnow; + + clock_gettime(CLOCK_MONOTONIC_RAW, &rnow); + + struct timespec rdeadline; + + while(valread < read_len){ + + clock_gettime(CLOCK_MONOTONIC_RAW, &rdeadline); + + ms_until_deadline = ((rdeadline.tv_sec - rnow.tv_sec) * 1000 + (rdeadline.tv_nsec - rnow.tv_nsec) / 1000000); + + if(ms_until_deadline > HUB_TIMEOUT_MS){ + + printf("time limit exceeded\n"); + + free(rbuff_tmp); + + return -10; + } + + valread_tmp = SSL_read(sslfd, (void*)rbuff_tmp, read_len); + + if(valread_tmp <= 0){ + + if(errno == EAGAIN){ + + memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); + + valread_tmp = 0; + + continue; + } + + printf("read: client gone: %d\n", valread); + + free(rbuff_tmp); + + return -2; + } + + for(int i = 0 ; i < valread_tmp; i++){ + + int idx = valread + i; + + rbuff[idx] = rbuff_tmp[i]; + + } + + valread += valread_tmp; + + memset(rbuff_tmp, 0, read_len * sizeof(uint8_t)); + + valread_tmp = 0; + + } + + free(rbuff_tmp); + + return valread; + + +} + + + + + + + +void ctx_write_packet(struct HUB_PACKET* hp){ + + int valwrite = 0; + + + if(hp->ctx_type == ISSOCK){ + + valwrite = sockctx_write(hp->fd, HUB_HEADER_BYTELEN, hp->header); + + if(valwrite <= 0){ + + printf("packet send header failed\n"); + + hp->flag = valwrite; + + return; + + } + + uint8_t body_len_byte[HUB_BODY_BYTELEN] = {0}; + + uint64_t body_len_new = 0; + + body_len_new = htonll(hp->body_len); + + memcpy(body_len_byte, &body_len_new, HUB_BODY_BYTELEN); + + valwrite = sockctx_write(hp->fd, HUB_BODY_BYTELEN, body_len_byte); + + if(valwrite <= 0){ + + printf("packet send body len failed\n"); + + hp->flag = valwrite; + + return; + + } + + valwrite = sockctx_write(hp->fd, hp->body_len, hp->wbuff); + + if(valwrite <= 0){ + + printf("packet send buff failed\n"); + + hp->flag = valwrite; + + return; + + } + + hp->flag = valwrite; + + return; + + + } + + + printf("invalid ctx write packet type: %d\n", hp->ctx_type); + + hp->flag = valwrite; + + + return; + +} + + +void ctx_read_packet(struct HUB_PACKET* hp){ + + int valread = 0; + + if(hp->ctx_type == ISSOCK){ + + valread = sockctx_read(hp->fd, HUB_HEADER_BYTELEN, hp->header); + + if(valread <= 0){ + + printf("packet recv header failed\n"); + + hp->flag = valread; + + return; + + } + + uint8_t body_len_byte[HUB_BODY_BYTELEN] = {0}; + + uint64_t body_len = 0; + + valread = sockctx_read(hp->fd, HUB_BODY_BYTELEN, body_len_byte); + + if(valread <= 0){ + + printf("packet recv body len failed\n"); + + hp->flag = valread; + + return; + + } + + memcpy(&body_len, body_len_byte, HUB_BODY_BYTELEN); + + body_len = ntohll(body_len); + + if(body_len > HUB_BODY_BYTEMAX){ + + printf("packet body len too long \n"); + + hp->flag = -10; + + return; + } + + hp->body_len = body_len; + + hp->rbuff = (uint8_t*)malloc(hp->body_len * sizeof(uint8_t)); + + memset(hp->rbuff, 0, hp->body_len * sizeof(uint8_t)); + + valread = sockctx_read(hp->fd, hp->body_len, hp->rbuff); + + if(valread <= 0){ + + printf("packet recv body failed\n"); + + free(hp->rbuff); + + hp->flag = valread; + + return; + + } + + hp->flag = valread; + + return; + + + } + + + + + printf("invalid ctx read packet type: %d\n", hp->ctx_type); + + hp->flag = valread; + + return; +} + + + + + diff --git a/src/front/front.c b/src/front/front.c new file mode 100644 index 0000000..93efe96 --- /dev/null +++ b/src/front/front.c @@ -0,0 +1,451 @@ +#include "rat-chat/ctl.h" +#include "rat-chat/front/front.h" +#include "rat-chat/utils.h" + + +struct settings s_settings = {true, 1, 57, NULL}; + +uint64_t s_boot_timestamp = 0; + +char* s_json_header = + "Content-Type: application/json\r\n" + "Cache-Control: no-cache\r\n"; + +struct mg_mgr mgr; + +int s_sig_num = 0; + + +void sntp_fn(struct mg_connection *c, int ev, void *ev_data) { + uint64_t *expiration_time = (uint64_t *) c->data; + if (ev == MG_EV_OPEN) { + *expiration_time = mg_millis() + 3000; // Store expiration time in 3s + } else if (ev == MG_EV_SNTP_TIME) { + uint64_t t = *(uint64_t *) ev_data; + s_boot_timestamp = t - mg_millis(); + c->is_closing = 1; + } else if (ev == MG_EV_POLL) { + if (mg_millis() > *expiration_time) c->is_closing = 1; + } +} + + +void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time + mg_sntp_connect(param, "udp://time.google.com:123", sntp_fn, NULL); +} + + + + + + +void handle_healtiness_probe(struct mg_connection *c, struct mg_http_message *hm){ + + char* ticket[MAX_USER_PASS] = {0}; + + char rest_buff[MAX_REST_BUFF] = {0}; + + + cJSON* response = cJSON_CreateObject(); + + int datalen = 0; + + + + cJSON_AddItemToObject(response, "status", cJSON_CreateString("success")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("fine")); + + strcpy(rest_buff, cJSON_Print(response)); + + datalen = strlen(rest_buff); + + mg_http_reply(c, 200, "", rest_buff); + + + +} + + + + +void route(struct mg_connection *c, int ev, void *ev_data) { + + if (ev == MG_EV_ACCEPT) { + + if (c->fn_data != NULL) { + struct mg_tls_opts opts = {0}; + opts.cert = mg_unpacked("/certs/server_cert.pem"); + opts.key = mg_unpacked("/certs/server_key.pem"); + mg_tls_init(c, &opts); + } + + } else if (ev == MG_EV_HTTP_MSG) { + + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + + if (mg_match(hm->uri, mg_str("/api/healthz"), NULL)) { + + handle_healtiness_probe(c, hm); + + } + + printf("WS UPGRADE!!!!!\n"); + + mg_ws_upgrade(c, hm, NULL); + + if(DEBUG_THIS == 1){ + + MG_DEBUG(("%lu %.*s %.*s -> %.*s", c->id, (int) hm->method.len, + hm->method.buf, (int) hm->uri.len, hm->uri.buf, (int) 3, + &c->send.buf[9])); + + } + + } else if (ev == MG_EV_WS_MSG) { + + struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; + + front_handler(c, wm); + + } +} + + + +void* front_listen_and_serve(void* varg){ + + mg_mgr_init(&mgr); + + s_settings.device_name = strdup("rat-chat"); + + mg_http_listen(&mgr, HTTP_URL, route, NULL); + + + mg_timer_add(&mgr, 3600 * 1000, MG_TIMER_RUN_NOW | MG_TIMER_REPEAT, + timer_sntp_fn, &mgr); + + while (s_sig_num == 0) { + mg_mgr_poll(&mgr, 50); + } + + mg_mgr_free(&mgr); + +} + + + + +void front_handler(struct mg_connection *c, struct mg_ws_message *wm){ + + char ws_command[WS_MAX_COMMAND_LEN] = {0}; + + char ws_data[WS_MAX_COMMAND_DATA_LEN] = {0}; + + cJSON* response = cJSON_CreateObject(); + + pthread_mutex_lock(&G_MTX); + + int datalen = 0; + + int initial = 0; + + + int auth_chan_idx = front_authenticate(c, wm, &initial, ws_command, ws_data); + + if (auth_chan_idx < 0){ + + pthread_mutex_unlock(&G_MTX); + + return; + + } + + + if (initial == 1) { + + fmt_logln(LOGFP, "connection authenticated"); + + pthread_mutex_unlock(&G_MTX); + + return; + + } + + front_communicate(auth_chan_idx, ws_command, ws_data); + + pthread_mutex_unlock(&G_MTX); + +} + + + +int front_authenticate(struct mg_connection* c, struct mg_ws_message *wm, int* initial, char* command, char* data){ + + + char ws_buff[MAX_WS_BUFF] = {0}; + + cJSON* response = cJSON_CreateObject(); + + int datalen = 0; + + if(wm->data.len > MAX_WS_BUFF){ + + printf("failed handle ws: data too big\n"); + cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); + + strcpy(ws_buff, cJSON_Print(response)); + + datalen = strlen(ws_buff); + + mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); + + return -1; + } + + + cJSON* req_obj = cJSON_Parse(wm->data.buf); + + if(req_obj == NULL){ + + printf("failed handle ws: data invalid\n"); + + + cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); + + strcpy(ws_buff, cJSON_Print(response)); + + datalen = strlen(ws_buff); + + mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); + + return -2; + + } + + cJSON* ws_command = cJSON_GetObjectItemCaseSensitive(req_obj, "command"); + + if(ws_command == NULL){ + + printf("failed handle ws: data invalid\n"); + + cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); + + strcpy(ws_buff, cJSON_Print(response)); + + datalen = strlen(ws_buff); + + mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); + + return -3; + + } + + + + printf("command: %s\n", ws_command->valuestring); + + datalen = strlen(ws_command->valuestring); + + if(datalen > WS_MAX_COMMAND_LEN){ + + printf("failed handle ws: command too long\n"); + + cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); + + strcpy(ws_buff, cJSON_Print(response)); + + datalen = strlen(ws_buff); + + mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); + + return -4; + } + + + cJSON* ws_data = cJSON_GetObjectItemCaseSensitive(req_obj, "data"); + + if(ws_data == NULL){ + + printf("failed handle ws: no data field\n"); + + cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); + + strcpy(ws_buff, cJSON_Print(response)); + + datalen = strlen(ws_buff); + + mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); + + return -5; + + } + + int ws_data_len = strlen(ws_data->valuestring); + + if(ws_data_len > WS_MAX_COMMAND_DATA_LEN){ + + printf("failed handle ws: data len too long\n"); + + cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); + + strcpy(ws_buff, cJSON_Print(response)); + + datalen = strlen(ws_buff); + + mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); + + return -6; + + } + + int frontid = (int)c->id; + + char user_id[MAX_ID_LEN] = {0}; + + + // TODO: + // simple check + + int chan_idx = 0; + + if (chan_idx < 0){ + + fmt_logln(LOGFP,"not registered to chan ctx, auth"); + + int v = idpw_verify(ws_data->valuestring); + + if(v < 0){ + + fmt_logln(LOGFP,"invalid idpw"); + printf("failed handle ws: invalid idpw\n"); + cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("invalid idpw")); + + strcpy(ws_buff, cJSON_Print(response)); + + datalen = strlen(ws_buff); + + mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); + + return -10; + + } else { + + fmt_logln(LOGFP, "auth success"); + + + fmt_logln(LOGFP, "initial auth success"); + + printf("handle ws: initial auth success\n"); + cJSON_AddItemToObject(response, "status", cJSON_CreateString("success")); + cJSON_AddItemToObject(response, "data", cJSON_CreateString("accepted")); + + strcpy(ws_buff, cJSON_Print(response)); + + datalen = strlen(ws_buff); + + mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); + + *initial = 1; + + } + + } + + strcpy(command, ws_command->valuestring); + + strcpy(data, ws_data->valuestring); + + fmt_logln(LOGFP, "auth success"); + + return chan_idx; + + +} + + +void front_communicate(int chan_idx, char* command, char* data){ + + char ws_buff[MAX_WS_BUFF] = {0}; + + cJSON* response = cJSON_CreateObject(); + + int datalen = 0; + + fmt_logln(LOGFP, "incoming front communication to sock"); + + int sockfd = CHAN_CTX[chan_idx].sockfd; + + if(sockfd == 0){ + + + fmt_logln(LOGFP, "no sock exists for communication"); + + + return; + + } + + + fmt_logln(LOGFP, "sock exists"); + + struct HUB_PACKET hp; + + + if (strcmp(command, WS_COMMAND_ROUNDTRIP) == 0) { + + fmt_logln(LOGFP, "roundtrip"); + + + memset(hp.header, 0, HUB_HEADER_BYTELEN); + + memset(hp.wbuff, 0, MAX_BUFF); + + hp.ctx_type = CHAN_ISSOCK; + + strcpy(hp.id, CHAN_CTX[chan_idx].id); + + strcpy(hp.header, HUB_HEADER_SENDSOCK); + + datalen = strlen(data); + + hp.body_len = datalen; + + strncpy(hp.wbuff, data, datalen); + + hp.flag = 0; + + ctx_write_packet(&hp); + + if(hp.flag <= 0){ + + fmt_logln(LOGFP, "failed to send to sock"); + + + + return; + } + + fmt_logln(LOGFP, "send to sock"); + + + } else { + + printf("failed handle ws: no such command\n"); + + + return; + + } + + return; + +} + + diff --git a/src/hubfront/core.c b/src/hubfront/core.c deleted file mode 100644 index c899687..0000000 --- a/src/hubfront/core.c +++ /dev/null @@ -1,450 +0,0 @@ -#include "rat-chat/front/core.h" -#include "rat-chat/utils.h" - - -struct settings s_settings = {true, 1, 57, NULL}; - -uint64_t s_boot_timestamp = 0; - -char* s_json_header = - "Content-Type: application/json\r\n" - "Cache-Control: no-cache\r\n"; - -struct mg_mgr mgr; - -int s_sig_num = 0; - - -void sntp_fn(struct mg_connection *c, int ev, void *ev_data) { - uint64_t *expiration_time = (uint64_t *) c->data; - if (ev == MG_EV_OPEN) { - *expiration_time = mg_millis() + 3000; // Store expiration time in 3s - } else if (ev == MG_EV_SNTP_TIME) { - uint64_t t = *(uint64_t *) ev_data; - s_boot_timestamp = t - mg_millis(); - c->is_closing = 1; - } else if (ev == MG_EV_POLL) { - if (mg_millis() > *expiration_time) c->is_closing = 1; - } -} - - -void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time - mg_sntp_connect(param, "udp://time.google.com:123", sntp_fn, NULL); -} - - - - - - -void handle_healtiness_probe(struct mg_connection *c, struct mg_http_message *hm){ - - char* ticket[MAX_USER_PASS] = {0}; - - char rest_buff[MAX_REST_BUFF] = {0}; - - - cJSON* response = cJSON_CreateObject(); - - int datalen = 0; - - - - cJSON_AddItemToObject(response, "status", cJSON_CreateString("success")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("fine")); - - strcpy(rest_buff, cJSON_Print(response)); - - datalen = strlen(rest_buff); - - mg_http_reply(c, 200, "", rest_buff); - - - -} - - - - -void route(struct mg_connection *c, int ev, void *ev_data) { - - if (ev == MG_EV_ACCEPT) { - - if (c->fn_data != NULL) { - struct mg_tls_opts opts = {0}; - opts.cert = mg_unpacked("/certs/server_cert.pem"); - opts.key = mg_unpacked("/certs/server_key.pem"); - mg_tls_init(c, &opts); - } - - } else if (ev == MG_EV_HTTP_MSG) { - - struct mg_http_message *hm = (struct mg_http_message *) ev_data; - - if (mg_match(hm->uri, mg_str("/api/healthz"), NULL)) { - - handle_healtiness_probe(c, hm); - - } - - printf("WS UPGRADE!!!!!\n"); - - mg_ws_upgrade(c, hm, NULL); - - if(DEBUG_THIS == 1){ - - MG_DEBUG(("%lu %.*s %.*s -> %.*s", c->id, (int) hm->method.len, - hm->method.buf, (int) hm->uri.len, hm->uri.buf, (int) 3, - &c->send.buf[9])); - - } - - } else if (ev == MG_EV_WS_MSG) { - - struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; - - front_handler(c, wm); - - } -} - - - -void* front_listen_and_serve(void* varg){ - - mg_mgr_init(&mgr); - - s_settings.device_name = strdup("rat-chat"); - - mg_http_listen(&mgr, HTTP_URL, route, NULL); - - - mg_timer_add(&mgr, 3600 * 1000, MG_TIMER_RUN_NOW | MG_TIMER_REPEAT, - timer_sntp_fn, &mgr); - - while (s_sig_num == 0) { - mg_mgr_poll(&mgr, 50); - } - - mg_mgr_free(&mgr); - -} - - - - -void front_handler(struct mg_connection *c, struct mg_ws_message *wm){ - - char ws_command[WS_MAX_COMMAND_LEN] = {0}; - - char ws_data[WS_MAX_COMMAND_DATA_LEN] = {0}; - - cJSON* response = cJSON_CreateObject(); - - pthread_mutex_lock(&G_MTX); - - int datalen = 0; - - int initial = 0; - - - int auth_chan_idx = front_authenticate(c, wm, &initial, ws_command, ws_data); - - if (auth_chan_idx < 0){ - - pthread_mutex_unlock(&G_MTX); - - return; - - } - - - if (initial == 1) { - - fmt_logln(LOGFP, "connection authenticated"); - - pthread_mutex_unlock(&G_MTX); - - return; - - } - - front_communicate(auth_chan_idx, ws_command, ws_data); - - pthread_mutex_unlock(&G_MTX); - -} - - - -int front_authenticate(struct mg_connection* c, struct mg_ws_message *wm, int* initial, char* command, char* data){ - - - char ws_buff[MAX_WS_BUFF] = {0}; - - cJSON* response = cJSON_CreateObject(); - - int datalen = 0; - - if(wm->data.len > MAX_WS_BUFF){ - - printf("failed handle ws: data too big\n"); - cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); - - strcpy(ws_buff, cJSON_Print(response)); - - datalen = strlen(ws_buff); - - mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); - - return -1; - } - - - cJSON* req_obj = cJSON_Parse(wm->data.buf); - - if(req_obj == NULL){ - - printf("failed handle ws: data invalid\n"); - - - cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); - - strcpy(ws_buff, cJSON_Print(response)); - - datalen = strlen(ws_buff); - - mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); - - return -2; - - } - - cJSON* ws_command = cJSON_GetObjectItemCaseSensitive(req_obj, "command"); - - if(ws_command == NULL){ - - printf("failed handle ws: data invalid\n"); - - cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); - - strcpy(ws_buff, cJSON_Print(response)); - - datalen = strlen(ws_buff); - - mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); - - return -3; - - } - - - - printf("command: %s\n", ws_command->valuestring); - - datalen = strlen(ws_command->valuestring); - - if(datalen > WS_MAX_COMMAND_LEN){ - - printf("failed handle ws: command too long\n"); - - cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); - - strcpy(ws_buff, cJSON_Print(response)); - - datalen = strlen(ws_buff); - - mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); - - return -4; - } - - - cJSON* ws_data = cJSON_GetObjectItemCaseSensitive(req_obj, "data"); - - if(ws_data == NULL){ - - printf("failed handle ws: no data field\n"); - - cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); - - strcpy(ws_buff, cJSON_Print(response)); - - datalen = strlen(ws_buff); - - mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); - - return -5; - - } - - int ws_data_len = strlen(ws_data->valuestring); - - if(ws_data_len > WS_MAX_COMMAND_DATA_LEN){ - - printf("failed handle ws: data len too long\n"); - - cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("null")); - - strcpy(ws_buff, cJSON_Print(response)); - - datalen = strlen(ws_buff); - - mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); - - return -6; - - } - - int frontid = (int)c->id; - - char user_id[MAX_ID_LEN] = {0}; - - - // TODO: - // simple check - - int chan_idx = 0; - - if (chan_idx < 0){ - - fmt_logln(LOGFP,"not registered to chan ctx, auth"); - - int v = idpw_verify(ws_data->valuestring); - - if(v < 0){ - - fmt_logln(LOGFP,"invalid idpw"); - printf("failed handle ws: invalid idpw\n"); - cJSON_AddItemToObject(response, "status", cJSON_CreateString("fail")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("invalid idpw")); - - strcpy(ws_buff, cJSON_Print(response)); - - datalen = strlen(ws_buff); - - mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); - - return -10; - - } else { - - fmt_logln(LOGFP, "auth success"); - - - fmt_logln(LOGFP, "initial auth success"); - - printf("handle ws: initial auth success\n"); - cJSON_AddItemToObject(response, "status", cJSON_CreateString("success")); - cJSON_AddItemToObject(response, "data", cJSON_CreateString("accepted")); - - strcpy(ws_buff, cJSON_Print(response)); - - datalen = strlen(ws_buff); - - mg_ws_send(c, ws_buff, datalen, WEBSOCKET_OP_TEXT); - - *initial = 1; - - } - - } - - strcpy(command, ws_command->valuestring); - - strcpy(data, ws_data->valuestring); - - fmt_logln(LOGFP, "auth success"); - - return chan_idx; - - -} - - -void front_communicate(int chan_idx, char* command, char* data){ - - char ws_buff[MAX_WS_BUFF] = {0}; - - cJSON* response = cJSON_CreateObject(); - - int datalen = 0; - - fmt_logln(LOGFP, "incoming front communication to sock"); - - int sockfd = CHAN_CTX[chan_idx].sockfd; - - if(sockfd == 0){ - - - fmt_logln(LOGFP, "no sock exists for communication"); - - - return; - - } - - - fmt_logln(LOGFP, "sock exists"); - - struct HUB_PACKET hp; - - - if (strcmp(command, WS_COMMAND_ROUNDTRIP) == 0) { - - fmt_logln(LOGFP, "roundtrip"); - - - memset(hp.header, 0, HUB_HEADER_BYTELEN); - - memset(hp.wbuff, 0, MAX_BUFF); - - hp.ctx_type = CHAN_ISSOCK; - - strcpy(hp.id, CHAN_CTX[chan_idx].id); - - strcpy(hp.header, HUB_HEADER_SENDSOCK); - - datalen = strlen(data); - - hp.body_len = datalen; - - strncpy(hp.wbuff, data, datalen); - - hp.flag = 0; - - ctx_write_packet(&hp); - - if(hp.flag <= 0){ - - fmt_logln(LOGFP, "failed to send to sock"); - - - - return; - } - - fmt_logln(LOGFP, "send to sock"); - - - } else { - - printf("failed handle ws: no such command\n"); - - - return; - - } - - return; - -} - - diff --git a/src/hubsock/core.c b/src/hubsock/core.c deleted file mode 100644 index 7de191a..0000000 --- a/src/hubsock/core.c +++ /dev/null @@ -1,672 +0,0 @@ -#include "rat-chat/sock/core.h" -#include "rat-chat/utils.h" - -int SOCK_FD; -int SOCK_SERVLEN; -int SOCK_EPLFD; -struct epoll_event SOCK_EVENT; -struct epoll_event *SOCK_EVENTARRAY; - -char CA_CERT[MAX_PW_LEN] = {0}; - -void sock_listen_and_serve(void* varg){ - - int result = 0; - - SSL_library_init(); - - result = read_file_to_buffer(CA_CERT, MAX_PW_LEN, HUB_CA_CERT); - - if(result < 0){ - - fmt_logln(LOGFP, "failed to read ca cert"); - - return; - - } - - - - struct sockaddr_in SERVADDR; - - for(int i = 0 ; i < MAX_CONN;i ++){ - - CHAN_CTX[i].ssl = NULL; - CHAN_CTX[i].ctx = NULL; - - - } - - - //signal(SIGPIPE, SIG_IGN); - - SOCK_FD = socket(AF_INET, SOCK_STREAM, 0); - - if (SOCK_FD == -1) { - - fmt_logln(LOGFP, "socket creation failed"); - - exit(EXIT_FAILURE); - } - else { - - fmt_logln(LOGFP, "socket successfully created"); - } - /* - if( setsockopt(SOCKFD, SOL_SOCKET, SO_REUSEADDR, (char *)&OPT, - sizeof(OPT)) < 0 ) - { - perror("setsockopt"); - exit(EXIT_FAILURE); - } - - */ - - - bzero(&SERVADDR, sizeof(SERVADDR)); - - SERVADDR.sin_family = AF_INET; - SERVADDR.sin_addr.s_addr = htonl(INADDR_ANY); - SERVADDR.sin_port = htons(PORT_SOCK); - - if ((bind(SOCK_FD, (struct sockaddr*)&SERVADDR, sizeof(SERVADDR))) != 0) { - - - fmt_logln(LOGFP, "socket bind failed"); - - exit(EXIT_FAILURE); - } - - if(make_socket_non_blocking(SOCK_FD) < 0){ - - fmt_logln(LOGFP, "non-blocking failed"); - - exit(EXIT_FAILURE); - } - - - if ((listen(SOCK_FD, MAX_CONN)) != 0) { - - fmt_logln(LOGFP, "listen failed"); - - exit(EXIT_FAILURE); - } - else{ - SOCK_SERVLEN = sizeof(SERVADDR); - } - - - SOCK_EPLFD = epoll_create1(0); - - if(SOCK_EPLFD == -1){ - - fmt_logln(LOGFP, "epoll creation failed"); - - exit(EXIT_FAILURE); - } - - SOCK_EVENT.data.fd = SOCK_FD; - SOCK_EVENT.events = EPOLLIN | EPOLLET; - - if (epoll_ctl(SOCK_EPLFD, EPOLL_CTL_ADD, SOCK_FD, &SOCK_EVENT) < 0){ - - fmt_logln(LOGFP,"epoll add failed"); - - exit(EXIT_FAILURE); - } - - SOCK_EVENTARRAY = calloc(MAX_CONN, sizeof(SOCK_EVENT)); - - - while(TRUE){ - - int n, i ; - - n = epoll_wait(SOCK_EPLFD, SOCK_EVENTARRAY, MAX_CONN, -1); - - for (i = 0 ; i < n; i ++){ - - if ( - (SOCK_EVENTARRAY[i].events & EPOLLERR) || - (SOCK_EVENTARRAY[i].events & EPOLLHUP) || - (!(SOCK_EVENTARRAY[i].events & EPOLLIN)) - ){ - - fmt_logln(LOGFP, "epoll wait error"); - - close(SOCK_EVENTARRAY[i].data.fd); - - continue; - - } else if (SOCK_FD == SOCK_EVENTARRAY[i].data.fd){ - - sock_handle_conn(); - - fmt_logln(LOGFP, "new sock conn successfully handled"); - - } else{ - - sock_handle_client(SOCK_EVENTARRAY[i].data.fd); - - fmt_logln(LOGFP, "socket data successfully handled"); - - - } - - } - - - } - - - free(SOCK_EVENTARRAY); - - close(SOCK_FD); - - close(SOCK_EPLFD); - - -} - - - - - -void sock_handle_conn(){ - - - while(TRUE){ - - struct sockaddr in_addr; - socklen_t in_len; - int infd; - SSL *ssl; - SSL_CTX *ctx; - - int ssl_accept_ret; - - in_len = sizeof(in_addr); - - infd = accept(SOCK_FD, &in_addr, &in_len); - - if(infd == -1){ - - if( - (errno == EAGAIN) || - (errno == EWOULDBLOCK) - ){ - - fmt_logln(LOGFP, "all incoming sock connections handled"); - - break; - - } else{ - - fmt_logln(LOGFP, "error handling incoming sock connection"); - - break; - } - } - - ctx = create_context(); - - configure_context(ctx); - - ssl = SSL_new(ctx); - - SSL_set_fd(ssl, infd); - - if((ssl_accept_ret = SSL_accept(ssl)) < 1){ - - int sslerr = SSL_get_error(ssl, 0); - - fmt_logln(LOGFP, "error handling tls handshake"); - - if (ssl_accept_ret <=0 && (sslerr == SSL_ERROR_WANT_READ)) { - - perror ("Need to wait until socket is readable."); - - fmt_logln(LOGFP, "ssl: %s", "Need to wait until socket is readable"); - - } else if (ssl_accept_ret <=0 && (sslerr == SSL_ERROR_WANT_WRITE)) { - - perror ("Need to wait until socket is writable."); - - fmt_logln(LOGFP, "ssl: %s", "Need to wait until socket is writable"); - - - } else { - perror ("Need to wait until socket is ready."); - - fmt_logln(LOGFP, "ssl: %s", "Need to wait until socket is ready"); - - } - - shutdown (infd, 2); - SSL_free (ssl); - SSL_CTX_free(ctx); - - continue; - - } - - - if(make_socket_non_blocking(infd) < 0){ - - fmt_logln(LOGFP, "failed new conn non block"); - - exit(EXIT_FAILURE); - } - - int sock_idx = set_sockctx_by_fd(infd); - - - - if(sock_idx < 0){ - - fmt_logln(LOGFP, "failed new conn sockctx"); - - exit(EXIT_FAILURE); - - } - - SOCK_CTX[sock_idx].ctx = ctx; - SOCK_CTX[sock_idx].ssl = ssl; - - - SOCK_EVENT.data.fd = infd; - SOCK_EVENT.events = EPOLLIN | EPOLLET; - - if (epoll_ctl(SOCK_EPLFD, EPOLL_CTL_ADD, infd, &SOCK_EVENT) < 0){ - - fmt_logln(LOGFP,"handle epoll add failed"); - - - exit(EXIT_FAILURE); - - } else { - - fmt_logln(LOGFP,"handle epoll add success"); - - } - - - - } - - - -} - - - -void sock_handle_client(int cfd){ - - - pthread_mutex_lock(&G_MTX); - - int sock_idx = get_sockctx_by_fd(cfd); - - - if(sock_idx < 0){ - - sock_authenticate(cfd); - - pthread_mutex_unlock(&G_MTX); - - return; - } - - int chan_idx = get_sockctx_chan_id_by_fd(cfd); - - if(chan_idx < 0){ - - sock_register(cfd); - - pthread_mutex_unlock(&G_MTX); - - return; - } - - sock_communicate(chan_idx, sock_idx); - - pthread_mutex_unlock(&G_MTX); - - return; - -} - - - -void sock_authenticate(int cfd){ - - int valread; - int valwrite; - - struct HUB_PACKET hp; - - - uint8_t id[MAX_ID_LEN] = {0}; - - int sock_idx = get_sockctx_by_fd(cfd); - - fmt_logln(LOGFP,"not registered to sock ctx, auth"); - - if(sock_idx < 0){ - - fmt_logln(LOGFP,"failed to get sock idx"); - - return; - } - - - hp.ctx_type = ISSOCK; - hp.fd = SOCK_CTX[sock_idx].sockfd; - - ctx_read_packet(&hp); - - if(hp.flag <= 0){ - - - fmt_logln(LOGFP,"failed to read sock"); - - free_sockctx(sock_idx, 1); - - return; - - } - - - - if(strcmp(hp.header, HUB_HEADER_AUTHSOCK) != 0){ - - fmt_logln(LOGFP,"not authenticate header: %s", hp.header); - - free_sockctx(sock_idx, 1); - - return; - - } - - - int verified = sig_verify(hp.rbuff, CA_CERT); - - if(verified < 1){ - - fmt_logln(LOGFP,"invalid signature"); - - free_sockctx(sock_idx, 1); - - free(hp.rbuff); - - return; - - } - - - - int ret = extract_common_name(id, hp.rbuff); - - if(ret != 1){ - - fmt_logln(LOGFP,"invalid id"); - - free_sockctx(sock_idx, 1); - - free(hp.rbuff); - - return; - - - } - - fmt_logln(LOGFP, "id: %s", id); - - free(hp.rbuff); - - ret = set_sockctx_id_by_fd(cfd, id); - - if (ret < 0){ - - fmt_logln(LOGFP, "failed to set sockctx"); - - free_sockctx(sock_idx, 1); - - free(hp.rbuff); - - return; - - } - - /* - - int chan_idx = update_chanctx_from_sockctx(cfd, id); - - if (chan_idx < 0){ - - fmt_logln(LOGFP, "failed to update chanctx"); - - free_sockctx(sock_idx, 1); - - return; - - } - - - */ - uint64_t body_len = strlen("SUCCESS") + 1; - - memset(hp.header, 0, HUB_HEADER_BYTELEN); - - memset(hp.wbuff, 0, MAX_BUFF); - - hp.ctx_type = CHAN_ISSOCK; - - strcpy(hp.header, HUB_HEADER_AUTHSOCK); - - hp.body_len = body_len; - - strcat(hp.wbuff,"SUCCESS"); - - strcpy(hp.id, id); - - fmt_logln(LOGFP, "writing auth result.."); - - ctx_write_packet(&hp); - - if(hp.flag <= 0){ - - fmt_logln(LOGFP, "failed to send"); - - return; - - } - - fmt_logln(LOGFP, "auth success sent"); - - return; - - -} - - -void sock_register(int cfd){ - - - int valread; - int valwrite; - - int result; - - int is_create; - - struct HUB_PACKET hp; - - - uint8_t id[MAX_ID_LEN] = {0}; - - int sock_idx = get_sockctx_by_fd(cfd); - - fmt_logln(LOGFP,"not registered to sock ctx, auth"); - - if(sock_idx < 0){ - - fmt_logln(LOGFP,"failed to get sock idx"); - - return; - } - - - hp.ctx_type = ISSOCK; - hp.fd = SOCK_CTX[sock_idx].sockfd; - - ctx_read_packet(&hp); - - if(hp.flag <= 0){ - - - fmt_logln(LOGFP,"failed to read sock"); - - free_sockctx(sock_idx, 1); - - return; - - } - - - if(strcmp(hp.header, HUB_HEADER_REGSOCK_CREATE) == 0){ - - is_create = 1; - - memcpy(id, hp.rbuff, MAX_ID_LEN); - - result = set_chanctx_by_id(id, 1, cfd); - - } else if (strcmp(hp.header, HUB_HEADER_REGSOCK_JOIN) == 0){ - - is_create = 0; - - memcpy(id, hp.rbuff, MAX_ID_LEN); - - result = set_chanctx_by_id(id, 0, cfd); - - } else { - - fmt_logln(LOGFP,"not register header: %s", hp.header); - - free_sockctx(sock_idx, 1); - - return; - - } - - - if (result < 0){ - - fmt_logln(LOGFP,"failed to register: result: %d", result); - - free_sockctx(sock_idx, 1); - - return; - } - - - uint64_t body_len = strlen("SUCCESS") + 1; - - memset(hp.header, 0, HUB_HEADER_BYTELEN); - - memset(hp.wbuff, 0, MAX_BUFF); - - hp.ctx_type = CHAN_ISSOCK; - - if(is_create == 1){ - - strcpy(hp.header, HUB_HEADER_REGSOCK_CREATE); - - } else { - - strcpy(hp.header, HUB_HEADER_REGSOCK_JOIN); - } - - - hp.body_len = body_len; - - strcat(hp.wbuff,"SUCCESS"); - - strcpy(hp.id, id); - - fmt_logln(LOGFP, "writing auth result.."); - - ctx_write_packet(&hp); - - if(hp.flag <= 0){ - - fmt_logln(LOGFP, "failed to send"); - - return; - - } - - fmt_logln(LOGFP, "register success sent"); - - return; - -} - - -void sock_communicate(int chan_idx, int sock_idx){ - - fmt_logln(LOGFP, "incoming sock communication "); - - - struct HUB_PACKET hp; - - hp.ctx_type = ISSOCK; - - hp.fd = SOCK_CTX[sock_idx].sockfd; - - ctx_read_packet(&hp); - - if(hp.flag <= 0){ - - fmt_logln(LOGFP, "failed to communicate sock read"); - - return; - - } - - memset(hp.header, 0, HUB_HEADER_BYTELEN); - - memset(hp.wbuff, 0, MAX_BUFF); - - hp.ctx_type = ISSOCK; - - //strcpy(hp.header, HUB_HEADER_RECVFRONT); - - strncpy(hp.wbuff, hp.rbuff, hp.body_len); - - hp.flag = 0; - - free(hp.rbuff); - - int counter = CHAN_CTX[chan_idx].fd_ptr; - - for(int i = 0; i < counter; i++){ - - hp.fd = CHAN_CTX[chan_idx].fds[i]; - - ctx_write_packet(&hp); - - if(hp.flag <= 0){ - - fmt_logln(LOGFP, "failed to send to peer: %d", i); - - continue; - } - } - - - fmt_logln(LOGFP, "sent to peer"); - - return; -} \ No newline at end of file diff --git a/src/sock/sock.c b/src/sock/sock.c new file mode 100644 index 0000000..23ee1ab --- /dev/null +++ b/src/sock/sock.c @@ -0,0 +1,698 @@ +#include "rat-chat/ctl.h" +#include "rat-chat/sock/sock.h" +#include "rat-chat/utils.h" + +int SOCK_FD; +int SOCK_SERVLEN; +int SOCK_EPLFD; +struct epoll_event SOCK_EVENT; +struct epoll_event *SOCK_EVENTARRAY; + +char CA_CERT[MAX_PW_LEN] = {0}; + +char CA_PRIV[MAX_PW_LEN] = {0}; + +char CA_PUB[MAX_PW_LEN] = {0}; + +void sock_listen_and_serve(void* varg){ + + int result = 0; + + SSL_library_init(); + + result = read_file_to_buffer(CA_CERT, MAX_PW_LEN, HUB_CA_CERT); + + if(result < 0){ + + fmt_logln(LOGFP, "failed to read ca cert"); + + return; + + } + + result = read_file_to_buffer(CA_PRIV, MAX_PW_LEN, HUB_CA_PRIV); + + if(result < 0){ + + fmt_logln(LOGFP, "failed to read ca priv"); + + return; + + } + + + result = read_file_to_buffer(CA_PUB, MAX_PW_LEN, HUB_CA_PUB); + + if(result < 0){ + + fmt_logln(LOGFP, "failed to read ca pub"); + + return; + + } + + + + struct sockaddr_in SERVADDR; + + for(int i = 0 ; i < MAX_CONN;i ++){ + + CHAN_CTX[i].ssl = NULL; + CHAN_CTX[i].ctx = NULL; + + + } + + + //signal(SIGPIPE, SIG_IGN); + + SOCK_FD = socket(AF_INET, SOCK_STREAM, 0); + + if (SOCK_FD == -1) { + + fmt_logln(LOGFP, "socket creation failed"); + + exit(EXIT_FAILURE); + } + else { + + fmt_logln(LOGFP, "socket successfully created"); + } + /* + if( setsockopt(SOCKFD, SOL_SOCKET, SO_REUSEADDR, (char *)&OPT, + sizeof(OPT)) < 0 ) + { + perror("setsockopt"); + exit(EXIT_FAILURE); + } + + */ + + + bzero(&SERVADDR, sizeof(SERVADDR)); + + SERVADDR.sin_family = AF_INET; + SERVADDR.sin_addr.s_addr = htonl(INADDR_ANY); + SERVADDR.sin_port = htons(PORT_SOCK); + + if ((bind(SOCK_FD, (struct sockaddr*)&SERVADDR, sizeof(SERVADDR))) != 0) { + + + fmt_logln(LOGFP, "socket bind failed"); + + exit(EXIT_FAILURE); + } + + if(make_socket_non_blocking(SOCK_FD) < 0){ + + fmt_logln(LOGFP, "non-blocking failed"); + + exit(EXIT_FAILURE); + } + + + if ((listen(SOCK_FD, MAX_CONN)) != 0) { + + fmt_logln(LOGFP, "listen failed"); + + exit(EXIT_FAILURE); + } + else{ + SOCK_SERVLEN = sizeof(SERVADDR); + } + + + SOCK_EPLFD = epoll_create1(0); + + if(SOCK_EPLFD == -1){ + + fmt_logln(LOGFP, "epoll creation failed"); + + exit(EXIT_FAILURE); + } + + SOCK_EVENT.data.fd = SOCK_FD; + SOCK_EVENT.events = EPOLLIN | EPOLLET; + + if (epoll_ctl(SOCK_EPLFD, EPOLL_CTL_ADD, SOCK_FD, &SOCK_EVENT) < 0){ + + fmt_logln(LOGFP,"epoll add failed"); + + exit(EXIT_FAILURE); + } + + SOCK_EVENTARRAY = calloc(MAX_CONN, sizeof(SOCK_EVENT)); + + + while(TRUE){ + + int n, i ; + + n = epoll_wait(SOCK_EPLFD, SOCK_EVENTARRAY, MAX_CONN, -1); + + for (i = 0 ; i < n; i ++){ + + if ( + (SOCK_EVENTARRAY[i].events & EPOLLERR) || + (SOCK_EVENTARRAY[i].events & EPOLLHUP) || + (!(SOCK_EVENTARRAY[i].events & EPOLLIN)) + ){ + + fmt_logln(LOGFP, "epoll wait error"); + + close(SOCK_EVENTARRAY[i].data.fd); + + continue; + + } else if (SOCK_FD == SOCK_EVENTARRAY[i].data.fd){ + + sock_handle_conn(); + + fmt_logln(LOGFP, "new sock conn successfully handled"); + + } else{ + + sock_handle_client(SOCK_EVENTARRAY[i].data.fd); + + fmt_logln(LOGFP, "socket data successfully handled"); + + + } + + } + + + } + + + free(SOCK_EVENTARRAY); + + close(SOCK_FD); + + close(SOCK_EPLFD); + + +} + + + + + +void sock_handle_conn(){ + + + while(TRUE){ + + struct sockaddr in_addr; + socklen_t in_len; + int infd; + SSL *ssl; + SSL_CTX *ctx; + + int ssl_accept_ret; + + in_len = sizeof(in_addr); + + infd = accept(SOCK_FD, &in_addr, &in_len); + + if(infd == -1){ + + if( + (errno == EAGAIN) || + (errno == EWOULDBLOCK) + ){ + + fmt_logln(LOGFP, "all incoming sock connections handled"); + + break; + + } else{ + + fmt_logln(LOGFP, "error handling incoming sock connection"); + + break; + } + } + + ctx = create_context(); + + configure_context(ctx); + + ssl = SSL_new(ctx); + + SSL_set_fd(ssl, infd); + + if((ssl_accept_ret = SSL_accept(ssl)) < 1){ + + int sslerr = SSL_get_error(ssl, 0); + + fmt_logln(LOGFP, "error handling tls handshake"); + + if (ssl_accept_ret <=0 && (sslerr == SSL_ERROR_WANT_READ)) { + + perror ("Need to wait until socket is readable."); + + fmt_logln(LOGFP, "ssl: %s", "Need to wait until socket is readable"); + + } else if (ssl_accept_ret <=0 && (sslerr == SSL_ERROR_WANT_WRITE)) { + + perror ("Need to wait until socket is writable."); + + fmt_logln(LOGFP, "ssl: %s", "Need to wait until socket is writable"); + + + } else { + perror ("Need to wait until socket is ready."); + + fmt_logln(LOGFP, "ssl: %s", "Need to wait until socket is ready"); + + } + + shutdown (infd, 2); + SSL_free (ssl); + SSL_CTX_free(ctx); + + continue; + + } + + + if(make_socket_non_blocking(infd) < 0){ + + fmt_logln(LOGFP, "failed new conn non block"); + + exit(EXIT_FAILURE); + } + + int sock_idx = set_sockctx_by_fd(infd); + + + + if(sock_idx < 0){ + + fmt_logln(LOGFP, "failed new conn sockctx"); + + exit(EXIT_FAILURE); + + } + + SOCK_CTX[sock_idx].ctx = ctx; + SOCK_CTX[sock_idx].ssl = ssl; + + + SOCK_EVENT.data.fd = infd; + SOCK_EVENT.events = EPOLLIN | EPOLLET; + + if (epoll_ctl(SOCK_EPLFD, EPOLL_CTL_ADD, infd, &SOCK_EVENT) < 0){ + + fmt_logln(LOGFP,"handle epoll add failed"); + + + exit(EXIT_FAILURE); + + } else { + + fmt_logln(LOGFP,"handle epoll add success"); + + } + + + + } + + + +} + + + +void sock_handle_client(int cfd){ + + + pthread_mutex_lock(&G_MTX); + + int sock_idx = get_sockctx_by_fd(cfd); + + + if(sock_idx < 0){ + + sock_authenticate(cfd); + + pthread_mutex_unlock(&G_MTX); + + return; + } + + int chan_idx = get_sockctx_chan_id_by_fd(cfd); + + if(chan_idx < 0){ + + sock_register(cfd); + + pthread_mutex_unlock(&G_MTX); + + return; + } + + sock_communicate(chan_idx, sock_idx); + + pthread_mutex_unlock(&G_MTX); + + return; + +} + + + +void sock_authenticate(int cfd){ + + int valread; + int valwrite; + + struct HUB_PACKET hp; + + + uint8_t id[MAX_ID_LEN] = {0}; + + int sock_idx = get_sockctx_by_fd(cfd); + + fmt_logln(LOGFP,"not registered to sock ctx, auth"); + + if(sock_idx < 0){ + + fmt_logln(LOGFP,"failed to get sock idx"); + + return; + } + + + hp.ctx_type = ISSOCK; + hp.fd = SOCK_CTX[sock_idx].sockfd; + + ctx_read_packet(&hp); + + if(hp.flag <= 0){ + + + fmt_logln(LOGFP,"failed to read sock"); + + free_sockctx(sock_idx, 1); + + return; + + } + + + + if(strcmp(hp.header, HUB_HEADER_AUTHSOCK) != 0){ + + fmt_logln(LOGFP,"not authenticate header: %s", hp.header); + + free_sockctx(sock_idx, 1); + + return; + + } + + + int verified = sig_verify(hp.rbuff, CA_CERT); + + if(verified < 1){ + + fmt_logln(LOGFP,"invalid signature"); + + free_sockctx(sock_idx, 1); + + free(hp.rbuff); + + return; + + } + + + + int ret = extract_common_name(id, hp.rbuff); + + if(ret != 1){ + + fmt_logln(LOGFP,"invalid id"); + + free_sockctx(sock_idx, 1); + + free(hp.rbuff); + + return; + + + } + + fmt_logln(LOGFP, "id: %s", id); + + free(hp.rbuff); + + ret = set_sockctx_id_by_fd(cfd, id); + + if (ret < 0){ + + fmt_logln(LOGFP, "failed to set sockctx"); + + free_sockctx(sock_idx, 1); + + free(hp.rbuff); + + return; + + } + + /* + + int chan_idx = update_chanctx_from_sockctx(cfd, id); + + if (chan_idx < 0){ + + fmt_logln(LOGFP, "failed to update chanctx"); + + free_sockctx(sock_idx, 1); + + return; + + } + + + */ + uint64_t body_len = strlen("SUCCESS") + 1; + + memset(hp.header, 0, HUB_HEADER_BYTELEN); + + memset(hp.wbuff, 0, MAX_BUFF); + + hp.ctx_type = CHAN_ISSOCK; + + strcpy(hp.header, HUB_HEADER_AUTHSOCK); + + hp.body_len = body_len; + + strcat(hp.wbuff,"SUCCESS"); + + strcpy(hp.id, id); + + fmt_logln(LOGFP, "writing auth result.."); + + ctx_write_packet(&hp); + + if(hp.flag <= 0){ + + fmt_logln(LOGFP, "failed to send"); + + return; + + } + + fmt_logln(LOGFP, "auth success sent"); + + return; + + +} + + +void sock_register(int cfd){ + + + int valread; + int valwrite; + + int result; + + int is_create; + + struct HUB_PACKET hp; + + + uint8_t id[MAX_ID_LEN] = {0}; + + int sock_idx = get_sockctx_by_fd(cfd); + + fmt_logln(LOGFP,"not registered to sock ctx, auth"); + + if(sock_idx < 0){ + + fmt_logln(LOGFP,"failed to get sock idx"); + + return; + } + + + hp.ctx_type = ISSOCK; + hp.fd = SOCK_CTX[sock_idx].sockfd; + + ctx_read_packet(&hp); + + if(hp.flag <= 0){ + + + fmt_logln(LOGFP,"failed to read sock"); + + free_sockctx(sock_idx, 1); + + return; + + } + + + if(strcmp(hp.header, HUB_HEADER_REGSOCK_CREATE) == 0){ + + is_create = 1; + + memcpy(id, hp.rbuff, MAX_ID_LEN); + + result = set_chanctx_by_id(id, 1, cfd); + + } else if (strcmp(hp.header, HUB_HEADER_REGSOCK_JOIN) == 0){ + + is_create = 0; + + memcpy(id, hp.rbuff, MAX_ID_LEN); + + result = set_chanctx_by_id(id, 0, cfd); + + } else { + + fmt_logln(LOGFP,"not register header: %s", hp.header); + + free_sockctx(sock_idx, 1); + + return; + + } + + + if (result < 0){ + + fmt_logln(LOGFP,"failed to register: result: %d", result); + + free_sockctx(sock_idx, 1); + + return; + } + + + uint64_t body_len = strlen("SUCCESS") + 1; + + memset(hp.header, 0, HUB_HEADER_BYTELEN); + + memset(hp.wbuff, 0, MAX_BUFF); + + hp.ctx_type = CHAN_ISSOCK; + + if(is_create == 1){ + + strcpy(hp.header, HUB_HEADER_REGSOCK_CREATE); + + } else { + + strcpy(hp.header, HUB_HEADER_REGSOCK_JOIN); + } + + + hp.body_len = body_len; + + strcat(hp.wbuff,"SUCCESS"); + + strcpy(hp.id, id); + + fmt_logln(LOGFP, "writing auth result.."); + + ctx_write_packet(&hp); + + if(hp.flag <= 0){ + + fmt_logln(LOGFP, "failed to send"); + + return; + + } + + fmt_logln(LOGFP, "register success sent"); + + return; + +} + + +void sock_communicate(int chan_idx, int sock_idx){ + + fmt_logln(LOGFP, "incoming sock communication "); + + + struct HUB_PACKET hp; + + hp.ctx_type = ISSOCK; + + hp.fd = SOCK_CTX[sock_idx].sockfd; + + ctx_read_packet(&hp); + + if(hp.flag <= 0){ + + fmt_logln(LOGFP, "failed to communicate sock read"); + + return; + + } + + memset(hp.header, 0, HUB_HEADER_BYTELEN); + + memset(hp.wbuff, 0, MAX_BUFF); + + hp.ctx_type = ISSOCK; + + //strcpy(hp.header, HUB_HEADER_RECVFRONT); + + strncpy(hp.wbuff, hp.rbuff, hp.body_len); + + hp.flag = 0; + + free(hp.rbuff); + + int counter = CHAN_CTX[chan_idx].fd_ptr; + + for(int i = 0; i < counter; i++){ + + hp.fd = CHAN_CTX[chan_idx].fds[i]; + + ctx_write_packet(&hp); + + if(hp.flag <= 0){ + + fmt_logln(LOGFP, "failed to send to peer: %d", i); + + continue; + } + } + + + fmt_logln(LOGFP, "sent to peer"); + + return; +} \ No newline at end of file