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

Support sending/receiving file descriptors over sockets #46328

Closed
robert-ancell opened this issue Jun 11, 2021 · 4 comments
Closed

Support sending/receiving file descriptors over sockets #46328

robert-ancell opened this issue Jun 11, 2021 · 4 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-io type-enhancement A request for a change that isn't a bug

Comments

@robert-ancell
Copy link
Contributor

On Linux you are able to send and receive file descriptors using Unix domain sockets. This is done using sendmsg/recvmsg instead of sendto/recvfrom. This is desirable when interfacing with services that make use of this functionality, for example DBus.

A proposed API would be something like:

var socketAddress = InternetAddress('/var/run/dbus/system_bus_socket', type: InternetAddressType.unix);
var socket = await RawSocket.connect(socketAddress, 0);
var data = [0];
var fd = getFileDescriptorFromSomewhere();
var message = SocketMessage([data], controlMessages: [SocketFileDescriptorMessage([fd])]);
socket.writeMessage(message);

var message = socket.readMessage();
for (var data in message.vectors) {
  processData(data);
}
for (var controlMessage in message.controlMessages) {
  if (message is SocketFileDescriptorMessage) {
    processFileDescriptors(message.fileDescriptors);
  }
}

This API is similar to the one used in GLib.

This new API would throw an exception on platforms that didn't support it.

@robert-ancell
Copy link
Contributor Author

See associated issue for making use of file descriptors in Dart.

@mraleph mraleph added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-io labels Jun 14, 2021
@a-siva a-siva added the type-enhancement A request for a change that isn't a bug label Jun 15, 2021
robert-ancell added a commit to robert-ancell/dart-sdk that referenced this issue Jun 28, 2021
robert-ancell added a commit to robert-ancell/dart-sdk that referenced this issue Jun 28, 2021
robert-ancell added a commit to robert-ancell/dart-sdk that referenced this issue Jun 28, 2021
robert-ancell added a commit to robert-ancell/dart-sdk that referenced this issue Jun 28, 2021
robert-ancell added a commit to robert-ancell/dart-sdk that referenced this issue Jun 28, 2021
@robert-ancell
Copy link
Contributor Author

I'll give a real world example of how this API will be consumed in DBus. D-DBus is the IPC mechanism used in Linux, and allows messages to be sent between processes containing file descriptors as well as common data types (integers, strings, arrays etc).

The first step is to update dbus.dart with Unix file descriptor support. This draft PR currently used integers for the file descriptors, which would need to be updated with the objects that have been proposed as a solution to hide these integers from Dart code.

An app could then send and receive messages containing file descriptors. The following example shows installing a firmware file with the firmware update daemon. This is triggered by making an IPC method call with the file descriptor of the firmware file. This allows the server process to read the file without sending the contents over IPC (which would be inefficient).

import 'package:dbus/dbus.dart';

// Load a firmware file.
var file = await File('v42.firmware').open();

// Ask the firmware update daemon to install this firmware. The file is passed as a file descriptor and will be read from the server process.
var client = DBusClient.system();
var fwupd = DBusRemoteObject(client, destination: 'org.freedesktop.fwupd', path: DBusObjectPath('/'));
await fwupd.callMethod('org.freedesktop.fwupd', 'Install', [DBusString('92ed499703fad3db5e91533af659487e89ab840d'), DBusUnixFd(file.fd), DBusDict.stringVariant({})]); 

copybara-service bot pushed a commit that referenced this issue Oct 8, 2021
… sockets, std streams via sockets.

This adds [sendMessage] and [receiveMessage] methods to [RawSocket] class. They are only supported on Linux at the moment as they require connection opened as unix domain socket connection.

This introduces [SocketControlMessage] class that represents a message sent via socket and also introduces [ResourceHandle] class that wraps [RandomAccessFile], [Socket]/[RawSocket]/[RawDatagramSocket], [Stdin]/[Stdout] for
marshalling/unmarshalling purposes.

Underlying OS implementation supports various kinds of control messages that can be passed via sockets, this CL only adds support for sending/receiving opened file description handles.
When receiving a message recipient can attempt to extract handles out of it via [tryExtractHandles]. It returns [null] if message has no handles to extract.

This is continuation of the work started on https://dart-review.googlesource.com/c/sdk/+/205067.

Bug: #46328
TEST=unix_socket_test

Change-Id: Ic9125b51dc80b677452e454366bae4118c298081
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212036
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
copybara-service bot pushed a commit that referenced this issue Oct 13, 2021
…et sendMessage/receiveMessage

Bug: #46328
Change-Id: Ibab66e04c61647968cc8531cfc7533f3a8d7daad
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/216700
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
@aam
Copy link
Contributor

aam commented Oct 18, 2021

@robert-ancell this has landed in dart and flutter. Can you let us know if what landed meets you needs please?

@aam aam closed this as completed Oct 18, 2021
@robert-ancell
Copy link
Contributor Author

@robert-ancell this has landed in dart and flutter. Can you let us know if what landed meets you needs please?

Thanks @aam! I've updated the dbus.dart branch and it's working great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-io type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants