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

Public API for clients #38

Closed
dbrgn opened this issue Jul 13, 2016 · 4 comments
Closed

Public API for clients #38

dbrgn opened this issue Jul 13, 2016 · 4 comments

Comments

@dbrgn
Copy link
Member

dbrgn commented Jul 13, 2016

This is not directly something related to the protocol, but should be implemented consistently across all clients. Therefore the issue in the meta repo.

How should we design the public API?

Right now, it works as follows in the Java version:

// create new instance
KeyStore permanentKey = new KeyStore();
SaltyRTC salty = new SaltyRTC(permanentKey, host, port, sslContext);
salty.connect()

// Wait until connected
salty.events.signalingStateChanged.register(new EventHandler<SignalingStateChangedEvent>() {
    @Override
    public boolean handle(SignalingStateChangedEvent event) {
        if (event.getState() == SignalingState.CONNECTED) {
            LOG.info("Connected!");
        }
    }
});

// Retrieve public permanent key and auth token
byte[] key = salty.getPublicPermanentKey();
byte[] token = salty.getAuthToken();

// Get current state
SignalingState state = salty.getSignalingState();

// Get current signaling channel
SignalingChannel channel = salty.getSignalingChannel();

// Send signaling data (e.g. offer, answer, ICE candidates)
salty.sendSignalingData(new Data("offer", "offer-string"));

// Wait for data (e.g. offer, answer, ICE candidates)
salty.events.data.register(new EventHandler<DataEvent>() {
    @Override
    public boolean handle(DataEvent event) {
        if (event.getData().getType() == "answer") {
            // handle
        }
    }
});

// Do handover
salty.handover(peerConnection);

Now the question is how to send user data. One approach is to wrap a data channel.

SecureDataChannel sc = salty.wrap(dataChannel);

The other approach would be to send data through the SaltyRTC instance.

salty.sendData(dataChannel, data);

I'd favor the second approach because it does not require wrapping (more code, more complexity, presence of encryption is not directly visible, more complexity decreases security). Otherwise users might mix up secure and non-secure data channels.

(Note that this does not yet consider the tasks system. But tasks need to be implementable outside of SaltyRTC, so it would not change much about the basics.)

@lgrahl
Copy link
Member

lgrahl commented Jul 13, 2016

I believe we should discuss what changes must be made to the API to support tasks first and then decide which way to follow. The result of this discussion should probably end up as a recommended API in the spec.

@dbrgn
Copy link
Member Author

dbrgn commented Jul 14, 2016

Another issue: Should we allow sending of strings through the wrapped data channel?

The current browser API supports sending of strings, blobs and arraybuffers. By simply encrypting and passing on data, we can handle arraybuffers, but not the other two. The problem is that we always encrypt bytes. If we encrypt multiple possible types, the receiver must know the type of the encoding.

I'm not sure how the DataChannel itself handles it, but we can't rely on that, as we always send encoded bytes. A workaround would be to prepend an encoding byte to the message before encrypting it.

Status quo: The user can only send binary data. That means that JSON must be manually encoded to UTF-8 on one side and decoded on the other side.

The other option would be to always use msgpack encoding instead of leaving the encoding up to the user. This way the user could also send simple objects directly through the data channel without worrying about encoding. (Note that this is not something that's supported by the data channel API.)

And a third option would be to offer both APIs: The regular secureDataChannel.send(data: ArrayBuffer) method and additionally a secureDataChannel.sendObject(data: string | object) method that would use msgpack.

I tend to stick to binary data only. Making it hard to send JSON is the biggest downside though.

@lgrahl
Copy link
Member

lgrahl commented Jul 14, 2016

The underlying SCTP protocol tells the data channels whether data is binary or string. That doesn't help us though as the data will always be binary.

For me it would be fine to tell the user that we only accept binary for now. I'd also be okay with a task that negotiates this (either binary only or a byte indicating which type is being used). But that's an improvement we can add to the specific task later on.

@lgrahl lgrahl added this to the Clean Up Protocol milestone Sep 1, 2016
@dbrgn
Copy link
Member Author

dbrgn commented Sep 13, 2016

Let's close this, as the implementations are already done. If the need for API changes arises, we can still open tickets for that.

@dbrgn dbrgn closed this as completed Sep 13, 2016
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

No branches or pull requests

2 participants