Skip to content

Commit

Permalink
fruity: Gracefully close TunnelConnection
Browse files Browse the repository at this point in the history
Co-authored-by: Håvard Sørbø <[email protected]>
  • Loading branch information
oleavr and hsorbo committed Nov 6, 2024
1 parent 667c749 commit 4fce1c4
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/fruity/device-monitor.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1624,7 +1624,7 @@ namespace Frida.Fruity {
public async void close (Cancellable? cancellable) throws IOError {
_discovery_service.close ();

tunnel_connection.cancel ();
yield tunnel_connection.cancel (cancellable);

if (ncm != null)
ncm.close ();
Expand Down Expand Up @@ -1805,7 +1805,7 @@ namespace Frida.Fruity {
public async void close (Cancellable? cancellable) throws IOError {
_discovery_service.close ();

tunnel_connection.cancel ();
yield tunnel_connection.cancel (cancellable);
}

public async IOStream open_tcp_connection (uint16 port, Cancellable? cancellable) throws Error, IOError {
Expand Down
68 changes: 55 additions & 13 deletions src/fruity/xpc.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@ namespace Frida.Fruity {
get;
}

public abstract void cancel ();
public abstract async void cancel (Cancellable? cancellable) throws IOError;

protected static Bytes make_handshake_request (size_t mtu) {
string body = Json.to_string (
Expand Down Expand Up @@ -1888,6 +1888,8 @@ namespace Frida.Fruity {
}
}

private Promise<bool> cancelled = new Promise<bool> ();

private TunnelParameters tunnel_params;
private VirtualNetworkStack _tunnel_netstack;

Expand Down Expand Up @@ -1926,12 +1928,6 @@ namespace Frida.Fruity {
);
}

public override void dispose () {
cancel ();

base.dispose ();
}

private async bool init_async (int io_priority, Cancellable? cancellable) throws Error, IOError {
var stream = yield netstack.open_tcp_connection (address, cancellable);

Expand Down Expand Up @@ -1975,9 +1971,15 @@ namespace Frida.Fruity {
return true;
}

public void cancel () {
public async void cancel (Cancellable? cancellable) throws IOError {
io_cancellable.cancel ();

try {
yield cancelled.future.wait_async (cancellable);
} catch (Error e) {
assert_not_reached ();
}

if (_tunnel_netstack != null)
_tunnel_netstack.stop ();
}
Expand All @@ -1992,6 +1994,18 @@ namespace Frida.Fruity {
} catch (GLib.Error e) {
}

var source = new IdleSource ();
source.set_callback (process_incoming_messages.callback);
source.attach (MainContext.get_thread_default ());
yield;

try {
yield connection.close_async ();
} catch (IOError e) {
}

cancelled.resolve (true);

close ();
}

Expand Down Expand Up @@ -2155,6 +2169,7 @@ namespace Frida.Fruity {
}

private Promise<bool> established = new Promise<bool> ();
private Promise<bool> cancelled = new Promise<bool> ();

private Stream? control_stream;
private TunnelParameters tunnel_params;
Expand Down Expand Up @@ -2240,7 +2255,7 @@ namespace Frida.Fruity {
}

public override void dispose () {
cancel ();
perform_teardown ();

base.dispose ();
}
Expand Down Expand Up @@ -2340,7 +2355,30 @@ namespace Frida.Fruity {
established.resolve (true);
}

public void cancel () {
public async void cancel (Cancellable? cancellable) throws IOError {
if (connection == null)
return;

if (streams.is_empty) {
perform_teardown ();
return;
}

foreach (int64 id in streams.keys)
connection.shutdown_stream (0, id, 0);
process_pending_writes ();

try {
yield cancelled.future.wait_async (cancellable);
} catch (Error e) {
assert_not_reached ();
}
}

private void perform_teardown () {
if (cancelled.future.ready)
return;

if (connection != null)
close ();
connection = null;
Expand All @@ -2365,6 +2403,8 @@ namespace Frida.Fruity {

if (_tunnel_netstack != null)
_tunnel_netstack.stop ();

cancelled.resolve (true);
}

private void on_stream_data_available (Stream stream, uint8[] data, out size_t consumed) {
Expand Down Expand Up @@ -2425,7 +2465,9 @@ namespace Frida.Fruity {

unowned uint8[] data = rx_buf[:n];

connection.read_packet (path, null, data, make_timestamp ());
var res = connection.read_packet (path, null, data, make_timestamp ());
if (res == NGTcp2.ErrorCode.DRAINING)
perform_teardown ();
} catch (GLib.Error e) {
return Source.REMOVE;
} finally {
Expand Down Expand Up @@ -2528,7 +2570,7 @@ namespace Frida.Fruity {
private bool on_expiry () {
int res = connection.handle_expiry (make_timestamp ());
if (res != 0) {
cancel ();
perform_teardown ();
return Source.REMOVE;
}

Expand Down Expand Up @@ -2567,7 +2609,7 @@ namespace Frida.Fruity {
uint64.FORMAT_MODIFIER + "u", app_error_code));
}

cancel ();
perform_teardown ();

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions vapi/libngtcp2.vapi
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace NGTcp2 {
public int read_packet (Path path, PacketInfo * pi, uint8[] pkt, Timestamp ts);

public int open_bidi_stream (out int64 stream_id, void * stream_user_data);
public int shutdown_stream (uint32 flags, int64 stream_id, uint64 app_error_code);

public ssize_t write_stream (Path * path, PacketInfo * pi, uint8[] dest, ssize_t * pdatalen, WriteStreamFlags flags,
int64 stream_id, uint8[]? data, Timestamp ts);
Expand Down

0 comments on commit 4fce1c4

Please sign in to comment.