Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rexec client and server #39

Merged
merged 11 commits into from
Nov 1, 2019
Merged

Conversation

reynir
Copy link
Member

@reynir reynir commented Sep 25, 2019

This PR adds functionality to the qrexec implementation such that receiving and sending qrexec rpc calls concurrently is possible.

I will need to review this myself again, but it seems to work provided mirage/ocaml-vchan#132 is merged.

@reynir
Copy link
Member Author

reynir commented Sep 26, 2019

Added @yomimono as co-author since a lot of the code was based on theirs (thanks!!)

@yomimono
Copy link
Contributor

please add @linse also :)

@reynir
Copy link
Member Author

reynir commented Sep 26, 2019

Done! :-)

@reynir
Copy link
Member Author

reynir commented Sep 28, 2019

I had a discussion with @cfcs regarding RExec.Client_flow.writef. It differs from RExec.Flow.writef in that it doesn't add a newline. We discussed renaming it RExec.Client_flow.writefmt and adding a RExec.Flow.writefmt with equivalent semantics.

@cfcs
Copy link
Contributor

cfcs commented Sep 29, 2019

leaving a note here about concatenating printf format6 values to avoid first evaluating, then string concatenating (for the \n thing)

# open CamlinternalFormatBasics ;;
# let f (Format (fmt, n)) =
  let joined = Format (concat_fmt fmt (Char_literal ('z', End_of_format)), "") in
  Printf.sprintf joined
in f "a %s " "b";;
- : string = "a b z"

So @hannesm suggested this instead:

let f fmt = Printf.sprintf (fmt ^^ "z") in f "a %s " "b";;
- : string = "a b z"

let next_msg t =
recv t.dstream >|= function
| `Ok (`Data_stdout, data) ->
t.stdout_buf <- Cstruct.append t.stdout_buf data;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the Cstruct.append here is superfluous since next_msg is only called in read when Cstruct.len t.stdout_buf = 0 && Cstruct.len t.stderr_buf = 0 ?

Is the append here to prevent making a reference to the data buffer or can we do t.stdout_buf <- data ;?

(ping @reynir @yomimono @linse )

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed it, and it seems to be a leftover from #36 which has read_line that would require buffering. I opted to not implement read_line when writing Client_flow. It should be safe to return directly from next_msg. I can also implement read_line if it's desired.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think read_line might make sense as a utility function for the line-based protocols, but let's not let that block this PR :)

lib/rExec.ml Outdated Show resolved Hide resolved
lib/rExec.ml Show resolved Hide resolved
lib/rExec.ml Outdated Show resolved Hide resolved
| `Ok (ty, _) ->
Log.err Formats.Qrexec.(fun f -> f "unexpected message of type %ld (%s) received; \
ignoring it" (int_of_type ty) (string_of_type ty));
`Ok t
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should err on the side of caution here and terminate? Do we anticipate any unhandled messages, or would this only happen in qrexec upgrades?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Qrexec version is negotiated when connecting, so I think this would only happen if the other end is misbehaving. How do you suggest we terminate?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would kill the flow from here if that makes sense?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See reynir#1 for a suggested implementation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Do we need to QV.disconnect t.dstream on Eof?

lib/rExec.ml Show resolved Hide resolved
lib/rExec.ml Show resolved Hide resolved
lib/rExec.ml Outdated Show resolved Hide resolved
lib/rExec.mli Show resolved Hide resolved
lib/rExec.mli Outdated Show resolved Hide resolved
@reynir
Copy link
Member Author

reynir commented Sep 30, 2019

The CI fails at OCaml 4.04.0. I use Hashtbl.find_opt which is from OCaml 4.05.0. Mirage requires OCaml >= 4.05.0, so I think the CI should be updated to reflect this. :-)

Copy link
Contributor

@cfcs cfcs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had some more uncommitted comments

lib/rExec.ml Show resolved Hide resolved
lib/rExec.ml Outdated Show resolved Hide resolved
lib/rExec.ml Outdated Show resolved Hide resolved
@hannesm
Copy link
Member

hannesm commented Oct 10, 2019

from what I understand (please correct me if I'm wrong)

thanks for reading, maybe we can converge to get this merged (and a mirage-qubes release)!?

@talex5 talex5 mentioned this pull request Oct 11, 2019
@reynir
Copy link
Member Author

reynir commented Oct 21, 2019

@hannesm sorry, I have been travelling with little opportunity for computer time. Yes, that is correct. I have adapted some of the suggestions made by @cfcs, and #44 ups the OCaml compiler version. What is still outstanding is:

I don't find the latter an issue personally, but I'm open for adding begin .. end. I am personally not interested in adding read_line, so I think it would be better as a separate PR. Regarding killing the flow I've made a PR to my own PR with an implementation that I'm considering reynir#1.

I would love to see this merged and released soon.

@cfcs
Copy link
Contributor

cfcs commented Oct 28, 2019

@reynir I'm happy with your kill flow implementation. I haven't tested it, but I think it looks reasonable, and I think we should get this merged.
My comments aside, all of which I consider addressed, are we ready to merge?

@hannesm
Copy link
Member

hannesm commented Oct 28, 2019

a rebase onto master would be great (than CI should pass AFAICT)!

yomimono and others added 11 commits October 28, 2019 11:08
Co-authored-by: linse <sschirme@gmail.com>
Co-authored-by: Mindy <meetup@yomimono.org>
Co-authored-by: linse <sschirme@gmail.com>
Instead of as debug messages. We would not want to hide these.
Co-Authored-By: C For C's Sake <cfcs@users.noreply.github.com>
We raise an exception if the arguments do not fit in the cstruct.

Also some whitespace changes.
Try to reflect that it's the remote service exit code
@cfcs
Copy link
Contributor

cfcs commented Oct 28, 2019

Looks like CI is happy :)

@hannesm
Copy link
Member

hannesm commented Oct 28, 2019

for me, the remaining question is about kill flow implementation -- reynir#1 (on unexpected message?, and EOF?) -- which is not part of this PR!?

@reynir
Copy link
Member Author

reynir commented Oct 28, 2019

I was considering doing kill flow in a separate PR. I noticed the existing server implementation did not close the flow either, but rereading the code now I noticed that it raises an exception (by Lwt.fail) on unexpected message types. It seems to me that a misbehaving client can then take down the whole unikernel?!

@hannesm
Copy link
Member

hannesm commented Nov 1, 2019

I agree with @reynir that the kill behaviour can be improved in a future PR (there are other components, such as qubesdb, which lead to Lwt.fail if they receive unexpected messages). Merging after review and ok from @cfcs to include into the next release. Thanks for your patience and submitting this PR!

@hannesm hannesm merged commit e9f455c into mirage:master Nov 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants