Created
April 9, 2025 18:30
-
-
Save gravicappa/6bb9dfa54cad1ffb9952398ade3f9f4d to your computer and use it in GitHub Desktop.
awa-ssh channel_data fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/channel.ml b/lib/channel.ml | |
index d7b8161..36e3ba8 100644 | |
--- a/lib/channel.ml | |
+++ b/lib/channel.ml | |
@@ -75,8 +75,8 @@ let input_data t data = | |
in | |
Ok (t, data, msg) | |
-let output_data t data = | |
- let fragment data = | |
+let output_data ?(flush = false) t data = | |
+ let fragment acc data = | |
let max_pkt = Int32.to_int t.them.max_pkt in | |
let i = | |
Cstruct.iter | |
@@ -90,15 +90,26 @@ let output_data t data = | |
in | |
Cstruct.fold (fun frags frag -> | |
Ssh.Msg_channel_data (t.them.id, frag) :: frags) | |
- i [] |> List.rev | |
+ i acc |> List.rev | |
in | |
let tosend = cs_join t.tosend data in | |
let len = min (Cstruct.length tosend) (Int32.to_int t.them.win) in | |
- let data, tosend = Cstruct.split tosend len in | |
+ let data, tosend = | |
+ if flush then | |
+ tosend, Cstruct.create 0 | |
+ else | |
+ Cstruct.split tosend len in | |
let win = Int32.sub t.them.win (Int32.of_int len) in | |
let* () = guard Int32.(win >= zero) "window underflow" in | |
let t = { t with tosend; them = { t.them with win } } in | |
- Ok (t, fragment data) | |
+ let adjust_window = | |
+ Ssh.Msg_channel_window_adjust (t.them.id, Int32.of_int len) in | |
+ Ok (t, fragment [adjust_window] data) | |
+ | |
+let flush t = | |
+ let data = t.tosend in | |
+ let t = { t with tosend = Cstruct.create 0 } in | |
+ output_data ~flush: true t data | |
let adjust_window t len = | |
let win = Int32.add t.them.win len in | |
@@ -106,7 +117,7 @@ let adjust_window t len = | |
let* () = guard Int32.(win > zero) "window overflow" in | |
let data = t.tosend in | |
let t = { t with tosend = Cstruct.create 0; them = { t.them with win } } in | |
- output_data t data | |
+ output_data ~flush: true t data | |
(* | |
* Channel database | |
diff --git a/lib/client.ml b/lib/client.ml | |
index aae56f5..dd316d6 100644 | |
--- a/lib/client.ml | |
+++ b/lib/client.ml | |
@@ -528,11 +528,13 @@ let eof ?(id = 0l) t = | |
match | |
let* () = guard (established t) "not yet established" in | |
let* c = guard_some (Channel.lookup id t.channels) "no such channel" in | |
+ let* c, frags = Channel.flush c in | |
+ let t' = { t with channels = Channel.update c t.channels } in | |
let msg = Ssh.Msg_channel_eof c.them.id in | |
- Ok (output_msg t msg) | |
+ Ok (output_msgs t' (List.append frags [msg])) | |
with | |
- | Error _ -> t, None | |
- | Ok (t, msg) -> t, Some msg | |
+ | Error _ -> t, [] | |
+ | Ok (t, msgs) -> t, msgs | |
let close ?(id = 0l) t = | |
match | |
diff --git a/lib/client.mli b/lib/client.mli | |
index 3cf73ef..ee8f2ff 100644 | |
--- a/lib/client.mli | |
+++ b/lib/client.mli | |
@@ -39,6 +39,6 @@ val outgoing_request : t -> ?id:int32 -> ?want_reply:bool -> | |
val outgoing_data : t -> ?id:int32 -> Cstruct.t -> | |
(t * Cstruct.t list, string) result | |
-val eof : ?id:int32 -> t -> t * Cstruct.t option | |
+val eof : ?id:int32 -> t -> t * Cstruct.t list | |
val close : ?id:int32 -> t -> t * Cstruct.t option |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment