Skip to content

Commit

Permalink
Merge branch 'hypfvieh:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
brett-smith authored Oct 11, 2023
2 parents 0c7b39d + 284de30 commit de7421f
Show file tree
Hide file tree
Showing 21 changed files with 464 additions and 100 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ The library will remain open source and MIT licensed and can still be used, fork
- Updated minimum required Java version to 17
- Improved handling of listening connections to allow proper bootstrapping the connection before actually starting accepting new connections (thanks to [brett-smith](https://github.com/brett-smith) ([#213](https://github.com/hypfvieh/dbus-java/issues/213)))
- Updated export-object documentation ([#236](https://github.com/hypfvieh/dbus-java/issues/236))
- Fixed issues with autoConnect option, added method to register to bus by 'Hello' message manually, thanks to [brett-smith](https://github.com/brett-smith) ([#238](https://github.com/hypfvieh/dbus-java/issues/238))

##### Changes in 4.3.1 (2023-10-03):
- Provide classloader to ServiceLoader in TransportBuilder (for loading actual transports) and AbstractTransport (for loading IMessageReader/Writer implementations), thanks to [cthbleachbit](https://github.com/cthbleachbit) ([#210](https://github.com/hypfvieh/dbus-java/issues/210), [PR#211](https://github.com/hypfvieh/dbus-java/issues/211))
Expand Down
100 changes: 67 additions & 33 deletions dbus-java-core/src/main/java/org/freedesktop/dbus/FileDescriptor.java
Original file line number Diff line number Diff line change
@@ -1,60 +1,94 @@
package org.freedesktop.dbus;

import org.freedesktop.dbus.exceptions.MarshallingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.freedesktop.dbus.spi.message.ISocketProvider;
import org.freedesktop.dbus.utils.ReflectionFileDescriptorHelper;

import java.lang.reflect.*;
import java.util.Optional;

/**
* Represents a FileDescriptor to be passed over the bus. Can be created from
* either an integer(gotten through some JNI/JNA/JNR call) or from a
* java.io.FileDescriptor.
*
* Represents a FileDescriptor to be passed over the bus. <br>
* Can be created from either an integer (gotten through some JNI/JNA/JNR call) or from a
* {@link java.io.FileDescriptor}.
*/
public class FileDescriptor {

private final Logger logger = LoggerFactory.getLogger(getClass());
public final class FileDescriptor {

private final int fd;

public FileDescriptor(int _fd) {
fd = _fd;
}

public FileDescriptor(java.io.FileDescriptor _data) throws MarshallingException {
fd = getFileDescriptor(_data);
}
/**
* Converts this DBus {@link FileDescriptor} to a {@link java.io.FileDescriptor}.<br>
* Tries to use the provided ISocketProvider if present first. <br>
* If not present or conversion failed, tries to convert using reflection.
*
* @param _provider provider or null
*
* @return java file descriptor
* @throws MarshallingException when converting fails
*/
public java.io.FileDescriptor toJavaFileDescriptor(ISocketProvider _provider) throws MarshallingException {
if (_provider != null) {
Optional<java.io.FileDescriptor> result = _provider.createFileDescriptor(fd);
if (result.isPresent()) {
return result.get();
}
}

public java.io.FileDescriptor toJavaFileDescriptor() throws MarshallingException {
return createFileDescriptorByReflection(fd);
return ReflectionFileDescriptorHelper.getInstance()
.flatMap(helper -> helper.createFileDescriptor(fd))
.orElseThrow(() -> new MarshallingException("Could not create new FileDescriptor instance"));
}

public int getIntFileDescriptor() {
return fd;
}

private int getFileDescriptor(java.io.FileDescriptor _data) throws MarshallingException {
Field declaredField;
try {
declaredField = _data.getClass().getDeclaredField("fd");
declaredField.setAccessible(true);
return declaredField.getInt(_data);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException _ex) {
logger.error("Could not get filedescriptor by reflection.", _ex);
throw new MarshallingException("Could not get member 'fd' of FileDescriptor by reflection!", _ex);
@Override
public boolean equals(Object _o) {
if (this == _o) {
return true;
}
if (_o == null || getClass() != _o.getClass()) {
return false;
}
FileDescriptor that = (FileDescriptor) _o;
return fd == that.fd;
}

@Override
public int hashCode() {
return fd;
}

private java.io.FileDescriptor createFileDescriptorByReflection(long _demarshallint) throws MarshallingException {
try {
Constructor<java.io.FileDescriptor> constructor = java.io.FileDescriptor.class.getDeclaredConstructor(int.class);
constructor.setAccessible(true);
return constructor.newInstance((int) _demarshallint);
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException _ex) {
logger.error("Could not create new FileDescriptor instance by reflection.", _ex);
throw new MarshallingException("Could not create new FileDescriptor instance by reflection", _ex);
@Override
public String toString() {
return FileDescriptor.class.getSimpleName() + "[fd=" + fd + "]";
}

/**
* Utility method to create a DBus {@link FileDescriptor} from a {@link java.io.FileDescriptor}.<br>
* Tries to use the provided ISocketProvider if present first.<br>
* If not present or conversion failed, tries to convert using reflection.
*
* @param _data file descriptor
* @param _provider socket provider or null
*
* @return DBus FileDescriptor
* @throws MarshallingException when conversion fails
*/
public static FileDescriptor fromJavaFileDescriptor(java.io.FileDescriptor _data, ISocketProvider _provider) throws MarshallingException {
if (_provider != null) {
Optional<Integer> result = _provider.getFileDescriptorValue(_data);
if (result.isPresent()) {
return new FileDescriptor(result.get());
}
}

return new FileDescriptor(ReflectionFileDescriptorHelper.getInstance()
.flatMap(helper -> helper.getFileDescriptorValue(_data))
.orElseThrow(() -> new MarshallingException("Could not get FileDescriptor value")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,10 @@ public TransportConfig getTransportConfig() {
return transport.getTransportConfig();
}

public boolean isFileDescriptorSupported() {
return transport.isFileDescriptorSupported();
}

@Override
public String toString() {
return getClass().getSimpleName() + "[address=" + busAddress + "]";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public final class TransportConfig {
private String fileGroup;

private byte endianess = BaseConnectionBuilder.getSystemEndianness();
private boolean registerSelf = true;

/**
* Unix file permissions to set on socket file if this is a server transport (ignored on Windows, does nothing if
Expand Down Expand Up @@ -151,6 +152,14 @@ public void setEndianess(byte _endianess) {
endianess = _endianess;
}

public boolean isRegisterSelf() {
return registerSelf;
}

public void setRegisterSelf(boolean _registerSelf) {
registerSelf = _registerSelf;
}

/**
* Toggles the busaddress to be a listening (server) or non listening (client) connection.
* @param _listening true to be a server connection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,19 @@ public X withAutoConnect(boolean _connect) {
return self();
}

/**
* Register the new connection on DBus using 'hello' message. Default is true.
*
* @param _register boolean
* @return this
*
* @since 5.0.0 - 2023-10-11
*/
public X withRegisterSelf(boolean _register) {
config.setRegisterSelf(_register);
return self();
}

/**
* Switch to the {@link SaslConfigBuilder} to configure the SASL authentication mechanism.<br>
* Use {@link SaslConfigBuilder#back()} to return to this builder when finished.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public final class DBusConnection extends AbstractConnection {
private final String machineId;
private DBus dbus;

/** Whether the connection was registered using 'Hello' message. */
private boolean registered;

/** Count how many 'connections' we manage internally.
* This is required because a {@link DBusConnection} to the same address will always return the same object and
* the 'real' disconnection should only occur when there is no second/third/whatever connection is left. */
Expand All @@ -73,10 +76,9 @@ private AtomicInteger getConcurrentConnections() {
/**
* Connect to bus and register if asked. Should only be called by Builder.
*
* @param _registerSelf true to register
* @throws DBusException if registering or connection fails
*/
void connect(boolean _registerSelf) throws DBusException {
void connectImpl() throws DBusException {
// start listening for calls
try {
listen();
Expand All @@ -89,14 +91,32 @@ void connect(boolean _registerSelf) throws DBusException {
addSigHandlerWithoutMatch(DBus.NameAcquired.class, h);

// register ourselves if not disabled
if (_registerSelf) {
dbus = getRemoteObject("org.freedesktop.DBus", "/org/freedesktop/DBus", DBus.class);
try {
busnames.add(dbus.Hello());
} catch (DBusExecutionException _ex) {
logger.debug("Error while doing 'Hello' handshake", _ex);
throw new DBusException(_ex.getMessage());
}
if (getTransportConfig().isRegisterSelf() && getTransport().isConnected()) {
register();
}
}

/**
* Register this connection on the bus using 'Hello' message.<br>
* Will do nothing if session was already registered.
*
* @throws DBusException when sending message fails
*
* @since 5.0.0 - 2023-10-11
*/
public void register() throws DBusException {
if (registered) {
return;
}

dbus = getRemoteObject("org.freedesktop.DBus", "/org/freedesktop/DBus", DBus.class);

try {
busnames.add(dbus.Hello());
registered = true;
} catch (DBusExecutionException _ex) {
logger.debug("Error while doing 'Hello' handshake", _ex);
throw new DBusException(_ex.getMessage(), _ex);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
public final class DBusConnectionBuilder extends BaseConnectionBuilder<DBusConnectionBuilder, DBusConnection> {

private final String machineId;
private boolean registerSelf = true;
private boolean shared = true;

private DBusConnectionBuilder(BusAddress _address, String _machineId) {
Expand Down Expand Up @@ -146,16 +145,6 @@ private static BusAddress validateTransportAddress(BusAddress _address) {
return address;

}
/**
* Register the new connection on DBus using 'hello' message. Default is true.
*
* @param _register boolean
* @return this
*/
public DBusConnectionBuilder withRegisterSelf(boolean _register) {
registerSelf = _register;
return this;
}

/**
* Use this connection as shared connection. Shared connection means that the same connection is used multiple times
Expand Down Expand Up @@ -199,7 +188,7 @@ public DBusConnection build() throws DBusException {

c.setDisconnectCallback(getDisconnectCallback());
c.setWeakReferences(isWeakReference());
c.connect(registerSelf);
c.connectImpl();
return c;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ private void authenticate(SocketChannel _sock) throws IOException {
private TransportConnection createInputOutput(SocketChannel _socket) {
IMessageReader reader = null;
IMessageWriter writer = null;
ISocketProvider providerImpl = null;
try {
for (ISocketProvider provider : spiLoader) {
logger.debug("Found ISocketProvider {}", provider);
Expand All @@ -244,6 +245,7 @@ private TransportConnection createInputOutput(SocketChannel _socket) {
writer = provider.createWriter(_socket);
if (reader != null && writer != null) {
logger.debug("Using ISocketProvider {}", provider);
providerImpl = provider;
break;
}
}
Expand All @@ -261,7 +263,7 @@ private TransportConnection createInputOutput(SocketChannel _socket) {
// allows it
}

return new TransportConnection(messageFactory, _socket, writer, reader);
return new TransportConnection(messageFactory, _socket, providerImpl, writer, reader);
}

/**
Expand Down Expand Up @@ -313,6 +315,10 @@ public TransportConfig getTransportConfig() {
return config;
}

public boolean isFileDescriptorSupported() {
return fileDescriptorSupported;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getSimpleName());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.freedesktop.dbus.connections.transports;

import org.freedesktop.dbus.messages.MessageFactory;
import org.freedesktop.dbus.spi.message.IMessageReader;
import org.freedesktop.dbus.spi.message.IMessageWriter;
import org.freedesktop.dbus.spi.message.*;

import java.io.Closeable;
import java.io.IOException;
Expand All @@ -27,12 +26,14 @@ public class TransportConnection implements Closeable {
private final SocketChannel channel;
private final IMessageWriter writer;
private final IMessageReader reader;
private final ISocketProvider socketProviderImpl;

private final MessageFactory messageFactory;

public TransportConnection(MessageFactory _factory, SocketChannel _channel, IMessageWriter _writer, IMessageReader _reader) {
public TransportConnection(MessageFactory _factory, SocketChannel _channel, ISocketProvider _socketProviderImpl, IMessageWriter _writer, IMessageReader _reader) {
messageFactory = _factory;
channel = _channel;
socketProviderImpl = _socketProviderImpl;
writer = _writer;
reader = _reader;
}
Expand All @@ -49,6 +50,10 @@ public IMessageReader getReader() {
return reader;
}

public ISocketProvider getSocketProviderImpl() {
return socketProviderImpl;
}

public long getId() {
return id;
}
Expand Down
Loading

0 comments on commit de7421f

Please sign in to comment.