Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gravicappa/6bb9dfa54cad1ffb9952398ade3f9f4d to your computer and use it in GitHub Desktop.
Save gravicappa/6bb9dfa54cad1ffb9952398ade3f9f4d to your computer and use it in GitHub Desktop.
awa-ssh channel_data fix
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