]> jxnshi.xyz Git - mesange.git/commitdiff
Request finally goes throuh, at least for subscribe
authorjxnshi <jxnshi@proton.me>
Tue, 11 Feb 2025 14:06:42 +0000 (15:06 +0100)
committerjxnshi <jxnshi@proton.me>
Tue, 11 Feb 2025 14:06:42 +0000 (15:06 +0100)
client-cli/client-cli
client-cli/command.odin
client-cli/host.odin
client-cli/main.odin
client-cli/state.odin
common/request.odin
common/util.odin [new file with mode: 0644]
server/client.odin
server/main.odin
server/server

index 1910a97ea8bbc025248607ea87f0b6269dfc666d..1a29f1057726f2c4c34dbc1b4b5e116a827c825a 100755 (executable)
Binary files a/client-cli/client-cli and b/client-cli/client-cli differ
index 878906737fba36109995beceefb7091e55b53132..40e8e4c701124689fc1f474fe11f42243f2aa611 100644 (file)
@@ -108,15 +108,17 @@ handle_command :: proc(app: ^App, command: string) -> Maybe(Handle_Command_Error
                 room_id = room_get_id(&room),
             }
 
-            request_id, err := request_host(app, request, &app.profile.private_key)
+            callback :: proc(app: ^App, response: common.Server_Response) {
+                
+            }
+
+            err := request_host(app, request, &app.profile.private_key, callback)
 
             if err != nil {
                 app_set_info_bar(app, "Could not subscribe to room.")
                 return .Command_Failed
             }
 
-            response := wait_host_response(app, request_id)
-
             app_add_room(app, room)
             app_set_info_bar(app, "Room added.")
 
@@ -144,17 +146,17 @@ handle_command :: proc(app: ^App, command: string) -> Maybe(Handle_Command_Error
                 room_id = room_get_id(&room),
             }
 
-            request_id, err := request_host(app, request, &app.profile.private_key)
+            callback :: proc(app: ^App, response: common.Server_Response) {
+                log.debug("Response %v", response)
+            }
+
+            err := request_host(app, request, &app.profile.private_key, callback)
 
             if err != nil {
                 app_set_info_bar(app, "Could not subscribe to room.")
                 return .Command_Failed
             }
 
-            response := wait_host_response(app, request_id)
-
-            log.infof("Response %v", response)
-
             app_add_room(app, room)
             app_set_info_bar(app, "Room generated.")
 
@@ -196,16 +198,16 @@ handle_command :: proc(app: ^App, command: string) -> Maybe(Handle_Command_Error
                 room_id = room_get_id(room),
             }
 
-            // request_id, err := request_host(app, request, &app.profile.private_key)
-
-            // if err != nil {
-            //     app_set_info_bar(app, "Could not subscribe to room.")
-            //     return .Command_Failed
-            // }
+            callback :: proc(app: ^App, response: common.Server_Response) {
+                
+            }
 
-            // response := wait_host_response(app, request_id)
+            err := request_host(app, request, &app.profile.private_key, callback)
 
-            // log.infof("Response %v", response)
+            if err != nil {
+                app_set_info_bar(app, "Could not subscribe to room.")
+                return .Command_Failed
+            }
 
             app_remove_room(app, app.selected_room)
             app_set_info_bar(app, "Room removed.")
index 4b4cd7ccd88549fb836ff3e96cbf8eb44edc0019..283c3bf5d1fb256513f3d6d87f6ec85e1be6000b 100644 (file)
@@ -4,7 +4,6 @@ import "core:bytes"
 import "core:crypto/ed25519"
 import "core:encoding/endian"
 import "core:io"
-import "core:log"
 import "core:math/rand"
 import "core:mem"
 import "core:net"
@@ -14,11 +13,14 @@ import "core:time"
 
 import "../common"
 
+Request_Callback :: proc(app: ^App, response: common.Server_Response)
+
 request_host :: proc(
     app: ^App,
     inner: common.Client_Request_Inner,
-    private_key: ^ed25519.Private_Key
-) -> (id: u32, err: common.Error) {
+    private_key: ^ed25519.Private_Key,
+    callback: Request_Callback,
+) -> common.Error {
     request: common.Client_Request
     ed25519.public_key_set_priv(&request.public_key, private_key)
     request.inner = inner
@@ -34,12 +36,10 @@ request_host :: proc(
     id_bytes: [size_of(u32)]u8
     _ = rand.read(id_bytes[:])
 
-    id, _ = endian.get_u32(id_bytes[:], .Little)
+    id, _ := endian.get_u32(id_bytes[:], .Little)
 
     _, _ = io.write(request_stream, id_bytes[:])
 
-    log.infof("ID %v", id_bytes)
-
     // Request.
     _ = common.client_request_to_bytes(request_stream, request)
 
@@ -56,7 +56,7 @@ request_host :: proc(
 
     _ = net.send_tcp(app.host.?, request_bytes) or_return
 
-    return id, nil
+    return nil
 }
 
 receive_host :: proc(app: ^App) -> (id: u32, message: common.Server_Message, err: common.Error) {
@@ -68,19 +68,3 @@ receive_host :: proc(app: ^App) -> (id: u32, message: common.Server_Message, err
 
     return common.server_message_from_bytes(app.host.?, packet_stream)
 }
-
-wait_host_response :: proc(app: ^App, id: u32) -> common.Server_Response {
-    for {
-        time.sleep(1_000_000)
-
-        sync.mutex_lock(&app.mutex)
-        defer sync.mutex_unlock(&app.mutex)
-
-        for res_id, response in app.waiting_responses {
-            if res_id == id {
-                delete_key(&app.waiting_responses, res_id)
-                return response
-            }
-        }
-    }
-}
index 24978b467a1bb316fade0d4aa71751fa4f583d4f..65e53f41c9fa507bed896f42e7dba479dc5623ff 100644 (file)
@@ -62,7 +62,7 @@ App :: struct {
     seed_phrase_checksum: u8,
 
     host: Maybe(net.TCP_Socket),
-    waiting_responses: map[u32]common.Server_Response,
+    requests_callbacks: map[u32]Request_Callback,
 
     selected_room: int,
 }
@@ -113,7 +113,7 @@ app_init :: proc(storage_path: string) -> App {
         info_bar = info_bar,
         input_window = input_window,
 
-        waiting_responses = make(map[u32]common.Server_Response),
+        requests_callbacks= make(map[u32]Request_Callback),
     }
 
     app_update_info_bar(&app)
@@ -127,11 +127,7 @@ app_deinit :: proc(app: ^App) {
     sync.mutex_lock(&app.mutex)
     defer sync.mutex_unlock(&app.mutex)
 
-    for _, response in app.waiting_responses {
-        common.server_response_deinit(response)
-    }
-
-    delete(app.waiting_responses)
+    delete(app.requests_callbacks)
 
     if host, ok := app.host.?; ok {
         net.close(host)
@@ -139,13 +135,13 @@ app_deinit :: proc(app: ^App) {
 
     profile_deinit(app.profile)
 
-    if len(app.profile_password) != 0 {
+    if app.profile_password != "" {
         delete(app.profile_password)
     }
 
     config_deinit(app.config)
 
-    if len(app.info_bar_content) != 0 {
+    if app.info_bar_content != "" {
         delete(app.info_bar_content)
     }
 
@@ -278,31 +274,38 @@ app_set_state :: proc(app: ^App, state: State) {
 }
 
 app_set_info_bar :: proc(app: ^App, format: string, args: ..any) {
-    if len(app.info_bar_content) != 0 {
-        delete(app.info_bar_content)
+    // FIXME
+    // ==========
+    // Setting info bar to empty string fucks up allocations
+    // for some reason ? If anyone got a fix please tell me.
+    // 
+    // If you're wondering what I'm talking about, remove the
+    // if statement below and read the logs in debug mode.
+    // ==========
+    if format == "" {
+        return
     }
 
     sync.mutex_lock(&app.mutex)
     defer sync.mutex_unlock(&app.mutex)
 
-    if len(format) == 0 {
-        app.info_bar_content = ""
-        app_update_info_bar(app)
+    if app.info_bar_content != "" {
+        delete(app.info_bar_content)
+    }
+
+    defer app_update_info_bar(app)
 
+    if format == "" {
+        app.info_bar_content = ""
         return
     }
 
     info_bar_content_builder: strings.Builder
-
     strings.builder_init_none(&info_bar_content_builder)
-    defer strings.builder_destroy(&info_bar_content_builder)
 
     fmt.sbprintf(&info_bar_content_builder, format, ..args)
 
-    app.info_bar_content = strings.clone(strings.to_string(info_bar_content_builder))
-    app_update_info_bar(app)
-
-    log.infof("Info bar %v", app.info_bar_content)
+    app.info_bar_content = strings.to_string(info_bar_content_builder)
 }
 
 app_set_box_message :: proc(app: ^App, lines: []string) {
@@ -674,6 +677,50 @@ handle_state :: proc(app: ^App) {
     }
 }
 
+handle_host :: proc(app: ^App) {
+    for {
+        defer {
+            time.sleep(1_000_000)
+            free_all(context.temp_allocator)
+        }
+
+        state: State
+
+        {
+            sync.mutex_lock(&app.mutex)
+            defer sync.mutex_unlock(&app.mutex)
+
+            state = app.state
+        }
+
+        #partial switch state {
+        case .Room_List, .Room:
+            message_id, server_message, err := receive_host(app)
+
+            if err != nil {
+                log.errorf("Failed to receive server message with error %v", err)
+                continue
+            }
+
+            #partial switch message in server_message {
+            case common.Server_Response:
+                response := message
+                callback: Request_Callback
+
+                {
+                    sync.mutex_lock(&app.mutex)
+                    defer sync.mutex_unlock(&app.mutex)
+
+                    callback = app.requests_callbacks[message_id]
+                    delete_key(&app.requests_callbacks, message_id)
+                }
+
+                callback(app, response)
+            }
+        }
+    }
+}
+
 main :: proc() {
     home_path := os.get_env("HOME")
     defer delete(home_path)
@@ -746,39 +793,32 @@ main :: proc() {
         thread.destroy(handle_state_thread)
     }
 
-    for app.running {
+    // Setup host thread context.
+    handle_host_thread_context := runtime.default_context()
+    handle_host_thread_context.allocator = context.allocator
+    handle_host_thread_context.logger = context.logger
+    handle_host_thread_context.random_generator = context.random_generator
+
+    defer free_all(handle_host_thread_context.temp_allocator)
+
+    handle_host_thread := thread.create_and_start_with_poly_data(&app, handle_host, handle_host_thread_context)
+
+    defer {
+        thread.terminate(handle_host_thread, 0)
+        thread.destroy(handle_host_thread)
+    }
+
+    for {
         defer {
             time.sleep(1_000_000)
             free_all(context.temp_allocator)
         }
 
-        state: State
-
-        {
-            sync.mutex_lock(&app.mutex)
-            defer sync.mutex_unlock(&app.mutex)
+        sync.mutex_lock(&app.mutex)
+        defer sync.mutex_unlock(&app.mutex)
 
-            state = app.state
+        if !app.running {
+            break
         }
-
-        // #partial switch state {
-        // case .Room_List, .Room:
-        //     message_id, server_message, err := receive_host(&app)
-
-        //     if err != nil {
-        //         log.errorf("Failed to receive server message with error %v", err)
-        //         continue
-        //     }
-
-        //     #partial switch message in server_message {
-        //     case common.Server_Response:
-        //         response := message
-
-        //         sync.mutex_lock(&app.mutex)
-        //         defer sync.mutex_unlock(&app.mutex)
-
-        //         app.waiting_responses[message_id] = response
-        //     }
-        // }
     }
 }
index 7ad97c90a450de9f57eed2c7f8663d7e5b31e92e..819f5191bcd4eb810197115c98aa8a52ad97f958 100644 (file)
@@ -549,7 +549,11 @@ state_room :: proc(app: ^App) {
             encrypted_message = encrypted_message,
         }
 
-        _, err := request_host(app, request, &app.profile.private_key)
+        callback :: proc(app: ^App, response: common.Server_Response) {
+            
+        }
+
+        err := request_host(app, request, &app.profile.private_key, callback)
 
         if err != nil {
             app_set_info_bar(app, "Failed to send message.")
index 1f6be342c67ac70a633da0960d1db2c1fca9f824..ae5ce7a99d5ecf7eebe64a20902250b0e0bb0f9a 100644 (file)
@@ -5,7 +5,6 @@ import "core:crypto/ed25519"
 import "core:crypto/sha3"
 import "core:encoding/endian"
 import "core:io"
-import "core:log"
 import "core:net"
 import "core:math/rand"
 import "core:mem"
@@ -130,15 +129,16 @@ Client_Request_Inner :: union {
 }
 
 client_request_inner_from_bytes :: proc(stream: io.Stream) -> (request: Client_Request_Inner, err: Error) {
-    kind, err1 := io.read_byte(stream)
-    if err1 != nil do return {}, err1
+    kind := io.read_byte(stream) or_return
 
     inner: Client_Request_Inner
 
     switch kind {
     case 0: inner = write_request_from_bytes(stream) or_return
+
     case 1: inner = subscribe_request_from_bytes(stream) or_return
     case 2: inner = unsubscribe_request_from_bytes(stream) or_return
+
     case: return {}, Client_Request_From_Bytes_Error.Invalid_Inner_Kind
     }
 
@@ -148,15 +148,15 @@ client_request_inner_from_bytes :: proc(stream: io.Stream) -> (request: Client_R
 client_request_inner_to_bytes :: proc(stream: io.Stream, inner: Client_Request_Inner) -> Error {
     switch i in inner {
     case Write_Request:
-        io.write_byte(stream, 2) or_return
+        io.write_byte(stream, 0) or_return
         write_request_to_bytes(stream, i) or_return
 
     case Subscribe_Request:
-        io.write_byte(stream, 0) or_return
+        io.write_byte(stream, 1) or_return
         subscribe_request_to_bytes(stream, i) or_return
 
     case Unsubscribe_Request:
-        io.write_byte(stream, 1) or_return
+        io.write_byte(stream, 2) or_return
         unsubscribe_request_to_bytes(stream, i) or_return
     }
 
@@ -171,23 +171,25 @@ Client_Request :: struct {
 }
 
 client_request_from_bytes :: proc(stream: io.Stream) -> (request: Client_Request, err: Error) {
+    // Pulic key.
     public_key_bytes: [ed25519.PUBLIC_KEY_SIZE]u8
 
     _ = io.read(stream, public_key_bytes[:]) or_return
 
-    log.infof("PK %v", public_key_bytes)
-
     public_key: ed25519.Public_Key
     ok := ed25519.public_key_set_bytes(&public_key, public_key_bytes[:])
     if !ok do return {}, .Invalid_Public_Key
 
+    // Inner.
     inner := client_request_inner_from_bytes(stream) or_return
 
+    // Timestamp.
     timestamp_bytes: [size_of(i64)]u8
     _ = io.read(stream, timestamp_bytes[:]) or_return
 
     timestamp, _ := endian.get_i64(timestamp_bytes[:], .Little)
 
+    // Signature.
     signature: [ed25519.SIGNATURE_SIZE]u8
     _ = io.read(stream, signature[:]) or_return
 
@@ -207,8 +209,6 @@ client_request_to_bytes_signatureless :: proc(stream: io.Stream, request: Client
     ed25519.public_key_bytes(&request.public_key, public_key_bytes[:])
     _ = io.write(stream, public_key_bytes[:]) or_return
 
-    log.infof("PK %v", public_key_bytes)
-
     client_request_inner_to_bytes(stream, request.inner) or_return
 
     timestamp_bytes: [size_of(i64)]u8
@@ -229,8 +229,7 @@ client_request_to_bytes :: proc(stream: io.Stream, request: Client_Request) -> E
 
 client_request_signature :: proc(request: Client_Request, private_key: ^ed25519.Private_Key) -> [ed25519.SIGNATURE_SIZE]u8 {
     bytes_buf: [10_000]u8
-    bytes_buffer: bytes.Buffer
-    bytes_buffer.buf = slice.into_dynamic(bytes_buf[:])
+    bytes_buffer := buffer_from_slice(bytes_buf[:])
     request_stream := bytes.buffer_to_stream(&bytes_buffer)
 
     _ = client_request_to_bytes_signatureless(request_stream, request)
@@ -255,8 +254,7 @@ client_request_verify :: proc(request: Client_Request, expiration: Maybe(i64)) -
     }
 
     bytes_buf: [10_000]u8
-    bytes_buffer: bytes.Buffer
-    bytes_buffer.buf = slice.into_dynamic(bytes_buf[:])
+    bytes_buffer := buffer_from_slice(bytes_buf[:])
     request_stream := bytes.buffer_to_stream(&bytes_buffer)
 
     _ = client_request_to_bytes_signatureless(request_stream, request)
diff --git a/common/util.odin b/common/util.odin
new file mode 100644 (file)
index 0000000..a0c058a
--- /dev/null
@@ -0,0 +1,14 @@
+package common
+
+import "base:runtime"
+
+import "core:bytes"
+import "core:slice"
+
+buffer_from_slice :: proc(s: []u8) -> bytes.Buffer {
+    bytes_buffer: bytes.Buffer
+    bytes_buffer.buf = slice.into_dynamic(s)
+    (^runtime.Raw_Dynamic_Array)(&bytes_buffer.buf).len = len(s)
+
+    return bytes_buffer
+}
index 9d47ae4f59b6b842406b1f3f80af122bf120c773..f086efc25fd3fb620a6c5709dc86ca754c9f28a9 100644 (file)
@@ -3,7 +3,6 @@ package main
 import "core:bytes"
 import "core:encoding/endian"
 import "core:io"
-import "core:log"
 import "core:net"
 import "core:slice"
 
@@ -16,11 +15,9 @@ receive_request :: proc(client: net.TCP_Socket) -> (id: u32, request: common.Cli
     id_bytes := packet[:size_of(u32)]
     id, _ = endian.get_u32(id_bytes[:], .Little)
 
-    log.infof("ID %v", id_bytes)
-
     request_bytes := packet[size_of(u32):]
-    request_buffer: bytes.Buffer
-    request_buffer.buf = slice.into_dynamic(request_bytes[:])
+
+    request_buffer := common.buffer_from_slice(request_bytes)
     request_stream := bytes.buffer_to_stream(&request_buffer)
 
     request, err = common.client_request_from_bytes(request_stream)
@@ -34,8 +31,7 @@ send_request :: proc(client: net.TCP_Socket, request: common.Server_Request) ->
 
 send_response :: proc(client: net.TCP_Socket, id: u32, content: string) -> common.Error {
     bytes_buf: [1_000]u8
-    bytes_buffer: bytes.Buffer
-    bytes_buffer.buf = slice.into_dynamic(bytes_buf[:])
+    bytes_buffer := common.buffer_from_slice(bytes_buf[:])
     response_stream := bytes.buffer_to_stream(&bytes_buffer)
 
     // Message type.
index 66e954e29b8d128489061151bdc9666d4114dbd8..aff299836d7e0dee837ae3560a5af81aa18692a2 100644 (file)
@@ -39,12 +39,11 @@ handle_client :: proc(data: Handle_Client_Data) {
     recv_buffer: [10_000]u8
     send_buffer: [10_000]u8
 
-    response: []u8
+    response: string
 
     for {
-        defer net.send_tcp(client_socket, response)
-
         request_id, request, err1 := receive_request(client_socket)
+        defer send_response(client_socket, request_id, response)
 
         if err1 != nil {
             #partial switch err in err1 {
@@ -61,18 +60,13 @@ handle_client :: proc(data: Handle_Client_Data) {
                 }
             }
 
-            log.infof("Request error %v", err1)
-
-            response_string := "Invalid request"
-            response = transmute([]u8)response_string
+            response := "Invalid request"
 
             continue
         }
 
         if err2 := common.client_request_verify(request, 1 * 60 * 60 * 1_000_000_000); err2 != nil {
-            response_string := "Invalid authentication"
-            response = transmute([]u8)response_string
-
+            response := "Invalid authentication"
             continue
         }
 
@@ -80,9 +74,7 @@ handle_client :: proc(data: Handle_Client_Data) {
 
         #partial switch inner in request.inner {
             case:
-                response_string := "Unhandled request type"
-                response = transmute([]u8)response_string
-
+                response := "Unhandled request type"
                 continue
         }
     }
index f3e1bc2d1464c930ea6dfa5a8692369938656526..469054ef3c06082d44b54f5cc9832c50379980c8 100755 (executable)
Binary files a/server/server and b/server/server differ