LIBS := -lpthread -lssl -lcrypto
-OBJS := core.o
+OBJS := ctl.o
OBJS += utils.o
OBJS += sock.o
OBJS += front.o
-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:
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:
+#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
-#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;
--- /dev/null
+#ifndef _FRANK_CLI_H_
+#define _FRANK_CLI_H_
+
+#include "rat-chat/core.h"
+
+
+
+
+
+void run_cli();
+
+
+void run_cli_test(int tc);
+
+
+
+
+
+
+#endif
#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
};
-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;
--- /dev/null
+#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
+++ /dev/null
-#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
--- /dev/null
+#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
+++ /dev/null
-#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
--- /dev/null
+#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
--- /dev/null
+#include "rat-chat/cli/cli.h"
+#include "rat-chat/utils.h"
+
+
+
+
+void run_cli(){
+
+
+
+}
+
+
+void run_cli_test(int tc){
+
+
+
+
+
+
+}
+
+
+
+++ /dev/null
-#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;
-}
-
-
-
-
-
--- /dev/null
+#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;
+}
+
+
+
+
+
--- /dev/null
+#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;
+
+}
+
+
+++ /dev/null
-#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;
-
-}
-
-
+++ /dev/null
-#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
--- /dev/null
+#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