}
}
+ request := common.Subscribe_Request{
+ room_id = room_get_id(&room),
+ }
+
+ err := common.request_server(app.host.?, request, &app.profile.private_key)
+
+ if err != nil {
+ app_set_info_bar(app, "Could not subscribe to room.")
+ return .Command_Failed
+ }
+
app_add_room(app, room)
app_set_info_bar(app, "Room added.")
return .Invalid_Arguments
}
+ request := common.Subscribe_Request{
+ room_id = room_get_id(&room),
+ }
+
+ err := common.request_server(app.host.?, request, &app.profile.private_key)
+
+ if err != nil {
+ app_set_info_bar(app, "Could not subscribe to room.")
+ return .Command_Failed
+ }
+
app_add_room(app, room)
app_set_info_bar(app, "Room generated.")
return nil
}
+ room := &app.profile.rooms[app.selected_room]
+
+ request := common.Unsubscribe_Request{
+ room_id = room_get_id(room),
+ }
+
+ err := common.request_server(app.host.?, request, &app.profile.private_key)
+
+ 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.")
import "core:crypto/sha3"
import "core:encoding/endian"
import "core:io"
+import "core:log"
import "core:net"
import "core:mem"
import "core:time"
Invalid_Signature,
}
-Join_Request :: struct {
+Write_Request :: struct {
room_id: [sha3.DIGEST_SIZE_256]u8,
+ message: [MESSAGE_SIZE]u8,
}
-join_request_from_bytes :: proc(stream: io.Stream) -> (request: Join_Request, err: From_Bytes_Error) {
+write_request_from_bytes :: proc(stream: io.Stream) -> (request: Write_Request, err: From_Bytes_Error) {
room_id: [sha3.DIGEST_SIZE_256]u8
_ = io.read(stream, room_id[:]) or_return
+ message: [MESSAGE_SIZE]u8
+ _ = io.read(stream, message[:]) or_return
+
return {
room_id = room_id,
+ message = message,
},
nil
}
-join_request_to_bytes :: proc(stream: io.Stream, request: Join_Request) -> io.Error {
+write_request_to_bytes :: proc(stream: io.Stream, request: Write_Request) -> io.Error {
request := request
+
_ = io.write(stream, request.room_id[:]) or_return
+ _ = io.write(stream, request.message[:]) or_return
return nil
}
-Leave_Request :: struct {
+Subscribe_Request :: struct {
room_id: [sha3.DIGEST_SIZE_256]u8,
}
-leave_request_from_bytes :: proc(stream: io.Stream) -> (request: Leave_Request, err: From_Bytes_Error) {
+subscribe_request_from_bytes :: proc(stream: io.Stream) -> (request: Subscribe_Request, err: From_Bytes_Error) {
room_id: [sha3.DIGEST_SIZE_256]u8
- _ = io.write(stream, request.room_id[:]) or_return
+ _ = io.read(stream, room_id[:]) or_return
return {
room_id = room_id,
nil
}
-leave_request_to_bytes :: proc(stream: io.Stream, request: Leave_Request) -> io.Error {
+subscribe_request_to_bytes :: proc(stream: io.Stream, request: Subscribe_Request) -> io.Error {
request := request
_ = io.write(stream, request.room_id[:]) or_return
return nil
}
-Write_Request :: struct {
+Unsubscribe_Request :: struct {
room_id: [sha3.DIGEST_SIZE_256]u8,
- message: [MESSAGE_SIZE]u8,
}
-write_request_from_bytes :: proc(stream: io.Stream) -> (request: Write_Request, err: From_Bytes_Error) {
+unsubscribe_request_from_bytes :: proc(stream: io.Stream) -> (request: Unsubscribe_Request, err: From_Bytes_Error) {
room_id: [sha3.DIGEST_SIZE_256]u8
- _ = io.read(stream, room_id[:]) or_return
-
- message: [MESSAGE_SIZE]u8
- _ = io.read(stream, message[:]) or_return
+ _ = io.write(stream, request.room_id[:]) or_return
return {
room_id = room_id,
- message = message,
},
nil
}
-write_request_to_bytes :: proc(stream: io.Stream, request: Write_Request) -> io.Error {
+unsubscribe_request_to_bytes :: proc(stream: io.Stream, request: Unsubscribe_Request) -> io.Error {
request := request
-
_ = io.write(stream, request.room_id[:]) or_return
- _ = io.write(stream, request.message[:]) or_return
return nil
}
Client_Request_Inner :: union {
- Join_Request,
- Leave_Request,
Write_Request,
+
+ Subscribe_Request,
+ Unsubscribe_Request,
}
client_request_inner_from_bytes :: proc(stream: io.Stream) -> (request: Client_Request_Inner, err: From_Bytes_Error) {
inner: Client_Request_Inner
switch kind {
- case 0: inner = join_request_from_bytes(stream) or_return
- case 1: inner = leave_request_from_bytes(stream) or_return
- case 2: inner = write_request_from_bytes(stream) or_return
+ 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 {}, Request_Validity_Error.Invalid_Inner_Kind
}
client_request_inner_to_bytes :: proc(stream: io.Stream, inner: Client_Request_Inner) -> io.Error {
switch i in inner {
- case Join_Request:
- io.write_byte(stream, 0) or_return
- join_request_to_bytes(stream, i) or_return
-
- case Leave_Request:
- io.write_byte(stream, 1) or_return
- leave_request_to_bytes(stream, i) or_return
-
case Write_Request:
io.write_byte(stream, 2) or_return
write_request_to_bytes(stream, i) or_return
+
+ case Subscribe_Request:
+ io.write_byte(stream, 0) or_return
+ subscribe_request_to_bytes(stream, i) or_return
+
+ case Unsubscribe_Request:
+ io.write_byte(stream, 1) or_return
+ unsubscribe_request_to_bytes(stream, i) or_return
}
return nil
request_stream := bytes.buffer_to_stream(&bytes_buffer)
_ = client_request_to_bytes(request_stream, request)
- _ = io.write_byte(request_stream, 0)
+
+ buffer_length := bytes.buffer_length(&bytes_buffer)
+
+ len_bytes: [size_of(32)]u8
+ endian.put_u32(len_bytes[:], .Little, u32(buffer_length))
request_bytes := bytes.buffer_to_bytes(&bytes_buffer)
+ log.infof("Preview %v", request_bytes[:1_000])
+
+ _, _ = io.write_at(request_stream, len_bytes[:], 0)
+
+ request_bytes = bytes.buffer_to_bytes(&bytes_buffer)
+
+ log.infof("Preview %v", request_bytes[:1_000])
+
_ = net.send_tcp(server, request_bytes) or_return
return nil
import "base:runtime"
-import "core:bytes"
+import "core:encoding/endian"
import "core:fmt"
import "core:io"
import "core:log"
import "../common"
+Packet_Error :: enum {
+ Packet_Too_Large,
+}
+
Recv_Packet_Error :: union {
+ Packet_Error,
io.Error,
net.Network_Error,
}
client_endpoint: net.Endpoint,
}
-receive_packet :: proc(socket: net.TCP_Socket, buffer: ^bytes.Buffer) -> (packet: []u8, err: Recv_Packet_Error) {
- escape := false
-
- for {
- byte_buf: [1]u8
- _ = net.recv_tcp(socket, byte_buf[:]) or_return
+receive_packet :: proc(socket: net.TCP_Socket, buffer: []u8) -> (packet: []u8, err: Recv_Packet_Error) {
+ length_bytes: [size_of(u32)]u8
+ _ = net.recv_tcp(socket, length_bytes[:]) or_return
- b := byte_buf[0]
+ length, _ := endian.get_u32(length_bytes[:], .Little)
- if escape {
- bytes.buffer_write_byte(buffer, b) or_return
- escape = false
- continue
+ if int(length) > len(buffer) {
+ for _ in 0..<length {
+ _ = net.recv_tcp(socket, buffer[:]) or_return
}
- switch b {
- case 0:
- return bytes.buffer_to_bytes(buffer), nil
+ return nil, .Packet_Too_Large
+ }
- case '\\':
- escape = true
- continue
- }
+ _ = net.recv_tcp(socket, buffer[:length]) or_return
- bytes.buffer_write_byte(buffer, b) or_return
- }
+ return buffer[:length], nil
}
handle_client :: proc(data: Handle_Client_Data) {
delete_key(clients_sockets, client_endpoint)
}
- recv_buf: [10_000]u8
- recv_buffer: bytes.Buffer
- bytes.buffer_init(&recv_buffer, recv_buf[:])
-
+ recv_buffer: [10_000]u8
send_buffer: [10_000]u8
response: []u8
for {
- packet, err1 := receive_packet(client_socket, &recv_buffer)
+ packet, err1 := receive_packet(client_socket, recv_buffer[:])
if err1 != nil {
- log.errorf("Failed to receive packet with error %v", err1)
+ #partial switch e in err1 {
+ case Packet_Error:
+ log.errorf("Failed to receive packet with error: %v", e)
+
+ case net.Network_Error:
+ #partial switch e_ in e {
+ case net.TCP_Recv_Error:
+ #partial switch e_ {
+ case .Connection_Closed:
+ return
+
+ case:
+ log.errorf("Failed to receive packet with error: %v", e_)
+ }
+
+ case:
+ log.errorf("Failed to receive packet with error: %v", e_)
+ }
+
+ case:
+ return
+ }
+
+ continue
}
defer net.send(client_socket, response)