From: jxnshi Date: Tue, 11 Feb 2025 14:06:42 +0000 (+0100) Subject: Request finally goes throuh, at least for subscribe X-Git-Url: https://jxnshi.xyz/repos?a=commitdiff_plain;h=1d1fcc1ffbc55b97c9fd1557785417ca5dcdc299;p=mesange.git Request finally goes throuh, at least for subscribe --- diff --git a/client-cli/client-cli b/client-cli/client-cli index 1910a97..1a29f10 100755 Binary files a/client-cli/client-cli and b/client-cli/client-cli differ diff --git a/client-cli/command.odin b/client-cli/command.odin index 8789067..40e8e4c 100644 --- a/client-cli/command.odin +++ b/client-cli/command.odin @@ -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.") diff --git a/client-cli/host.odin b/client-cli/host.odin index 4b4cd7c..283c3bf 100644 --- a/client-cli/host.odin +++ b/client-cli/host.odin @@ -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 - } - } - } -} diff --git a/client-cli/main.odin b/client-cli/main.odin index 24978b4..65e53f4 100644 --- a/client-cli/main.odin +++ b/client-cli/main.odin @@ -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 - // } - // } } } diff --git a/client-cli/state.odin b/client-cli/state.odin index 7ad97c9..819f519 100644 --- a/client-cli/state.odin +++ b/client-cli/state.odin @@ -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.") diff --git a/common/request.odin b/common/request.odin index 1f6be34..ae5ce7a 100644 --- a/common/request.odin +++ b/common/request.odin @@ -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 index 0000000..a0c058a --- /dev/null +++ b/common/util.odin @@ -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 +} diff --git a/server/client.odin b/server/client.odin index 9d47ae4..f086efc 100644 --- a/server/client.odin +++ b/server/client.odin @@ -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. diff --git a/server/main.odin b/server/main.odin index 66e954e..aff2998 100644 --- a/server/main.odin +++ b/server/main.odin @@ -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 } } diff --git a/server/server b/server/server index f3e1bc2..469054e 100755 Binary files a/server/server and b/server/server differ