]> git.feebdaed.xyz Git - socialize.git/commitdiff
working cli
authorseantywork <seantywork@gmail.com>
Wed, 19 Feb 2025 02:11:02 +0000 (11:11 +0900)
committerseantywork <seantywork@gmail.com>
Wed, 19 Feb 2025 02:11:02 +0000 (11:11 +0900)
17 files changed:
Makefile
cmd/cli/main.c
cmd/engine/main.c
include/rat-chat/cli/cli.h [new file with mode: 0644]
include/rat-chat/core.h
include/rat-chat/ctl.h [new file with mode: 0644]
include/rat-chat/front/core.h [deleted file]
include/rat-chat/front/front.h [new file with mode: 0644]
include/rat-chat/sock/core.h [deleted file]
include/rat-chat/sock/sock.h [new file with mode: 0644]
src/cli/cli.c [new file with mode: 0644]
src/core.c [deleted file]
src/ctl.c [new file with mode: 0644]
src/front/front.c [new file with mode: 0644]
src/hubfront/core.c [deleted file]
src/hubsock/core.c [deleted file]
src/sock/sock.c [new file with mode: 0644]

index 1816403ffc5b7fc9f85df35b9f942083ef8b7bf3..0836ffa30704ffb3c6efef458c64108b5d3ecb69 100644 (file)
--- 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:
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b88c30f89bca7a86d028370a9f3855bcd11f61a5 100644 (file)
@@ -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
index 6c3a564a5c150424b78b97e63af9e9ae28ef2d7e..4529fee1017993fc22ccf130af519b4df8221c26 100644 (file)
@@ -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 (file)
index 0000000..cba6282
--- /dev/null
@@ -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 
index 8a2a09529eaa9f269f32bdded591c54f9b0b4e1f..4c6c1a74a8b0c562684abd76dfc558f88048b1b8 100644 (file)
 #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 (file)
index 0000000..6df23c3
--- /dev/null
@@ -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 (file)
index bdababe..0000000
+++ /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 (file)
index 0000000..bdababe
--- /dev/null
@@ -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 (file)
index 0242b59..0000000
+++ /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 (file)
index 0000000..0242b59
--- /dev/null
@@ -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 (file)
index 0000000..95b4af8
--- /dev/null
@@ -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 (file)
index 400fcab..0000000
+++ /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 (file)
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 (file)
index 0000000..93efe96
--- /dev/null
@@ -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 (file)
index c899687..0000000
+++ /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 (file)
index 7de191a..0000000
+++ /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 (file)
index 0000000..23ee1ab
--- /dev/null
@@ -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