aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amat.us>2018-11-01 18:55:50 -0500
committerDavid Barksdale <amatus@amat.us>2018-11-01 18:55:50 -0500
commit5f6559d09a9685b840c8581ca871c2695eece5e0 (patch)
tree2f5cc1a8fa3728749588aa102f0e3978a7c950c3
parenta6e0620c4b4a31b2133f289f5fb5d013dfc4bb4b (diff)
That's the end of WebRTC, for now
-rw-r--r--README.md5
-rw-r--r--gnunet-build/packages/gnunet/gnunet/files/configuration.js2
-rw-r--r--gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc.c437
-rw-r--r--gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc_int.js30
4 files changed, 403 insertions, 71 deletions
diff --git a/README.md b/README.md
index 8d6ecf3..2c2e20d 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,8 @@ Roadmap
* No directory support.
* Release alpha.
* Write a WebRTC transport plugin.
- * Implement [RFC3264] over GNUnet.
+ * This is not currently possible, the Web Worker running the transport
+ service cannot access WebRTC, see [bug 4700].
What You Can Do Now
-------------------
@@ -67,8 +68,8 @@ To debug a shared worker in chrome open chrome://inspect and click the
[gnunet]: https://gnunet.org
[webrtc]: http://www.webrtc.org
[emscripten]: https://github.com/kripken/emscripten
- [rfc3264]: http://www.ietf.org/rfc/rfc3264.txt
[web worker]: http://www.w3.org/TR/workers/
[indexeddb]: http://www.w3.org/TR/IndexedDB/
[boot]: https://github.com/boot-clj/boot#install
+ [bug 4700]: https://bugs.chromium.org/p/webrtc/issues/detail?id=4700
diff --git a/gnunet-build/packages/gnunet/gnunet/files/configuration.js b/gnunet-build/packages/gnunet/gnunet/files/configuration.js
index f227ec6..d67d53f 100644
--- a/gnunet-build/packages/gnunet/gnunet/files/configuration.js
+++ b/gnunet-build/packages/gnunet/gnunet/files/configuration.js
@@ -25,7 +25,7 @@ mergeInto(LibraryManager.library, {
transport: {
UNIXPATH: 'transport',
NEIGHBOUR_LIMIT: 50,
- PLUGINS: 'http_client webrtc',
+ PLUGINS: 'http_client',
},
ats: {
UNIXPATH: 'ats',
diff --git a/gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc.c b/gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc.c
index 8204757..cea8633 100644
--- a/gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc.c
+++ b/gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc.c
@@ -24,22 +24,18 @@
*/
#include "platform.h"
-#include "gnunet_util_lib.h"
+#include "gnunet_cadet_service.h"
#include "gnunet_protocols.h"
#include "gnunet_statistics_service.h"
-#include "gnunet_transport_service.h"
#include "gnunet_transport_plugin.h"
+#include "gnunet_transport_service.h"
+#include "gnunet_util_lib.h"
+#define PLUGIN_NAME "webrtc"
#define LOG(kind,...) GNUNET_log_from (kind, PLUGIN_NAME,__VA_ARGS__)
-/**
- * After how long do we expire an address that we
- * learned from another peer if it is not reconfirmed
- * by anyone?
- */
-#define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1)
-
-#define PLUGIN_NAME "webrtc"
+#define MESSAGE_TYPE_WEBRTC_OFFER 1
+#define MESSAGE_TYPE_WEBRTC_ANSWER 2
/**
* Encapsulation of all of the state of the plugin.
@@ -53,20 +49,24 @@ struct Plugin;
struct GNUNET_ATS_Session
{
/**
- * To whom are we talking to (set to our identity
- * if we are still waiting for the welcome message)
+ * To whom are we talking.
*/
- struct GNUNET_PeerIdentity sender;
+ struct GNUNET_PeerIdentity peer;
/**
- * Stored in a linked list (or a peer map, or ...)
+ * Pointer to the global plugin struct.
*/
- struct GNUNET_ATS_Session *next;
+ struct Plugin *plugin;
/**
- * Pointer to the global plugin struct.
+ * Cadet channel for SDP exchange.
*/
- struct Plugin *plugin;
+ struct GNUNET_CADET_Channel *channel;
+
+ /**
+ * Handle to RTCPeerConnection
+ */
+ int rtc_peer_connection;
/**
* The client (used to identify this connection)
@@ -115,9 +115,9 @@ struct Plugin
struct GNUNET_TRANSPORT_PluginEnvironment *env;
/**
- * List of open sessions (or peer map, or...)
+ * Open sessions.
*/
- struct GNUNET_ATS_Session *sessions;
+ struct GNUNET_CONTAINER_MultiPeerMap *sessions;
/**
* Function to call about session status changes.
@@ -128,10 +128,24 @@ struct Plugin
* Closure for @e sic.
*/
void *sic_cls;
+
+ /**
+ * Cadet service handle.
+ */
+ struct GNUNET_CADET_Handle *cadet;
+
+ /**
+ * Cadet port for incoming connections.
+ */
+ struct GNUNET_CADET_Port *in_port;
+
+ /**
+ * Pre-computed port "number".
+ */
+ struct GNUNET_HashCode port;
};
-#if 0
/**
* If a session monitor is attached, notify it about the new
* session state.
@@ -161,7 +175,6 @@ notify_session_monitor (struct Plugin *plugin,
session,
&info);
}
-#endif
/**
@@ -220,8 +233,9 @@ static void
webrtc_plugin_disconnect_peer (void *cls,
const struct GNUNET_PeerIdentity *target)
{
- // struct Plugin *plugin = cls;
- // FIXME
+ struct Plugin *plugin = cls;
+
+ GNUNET_break (0);
}
@@ -238,8 +252,9 @@ static int
webrtc_plugin_disconnect_session (void *cls,
struct GNUNET_ATS_Session *session)
{
- // struct Plugin *plugin = cls;
- // FIXME
+ struct Plugin *plugin = cls;
+
+ GNUNET_break (0);
return GNUNET_SYSERR;
}
@@ -255,7 +270,7 @@ webrtc_plugin_disconnect_session (void *cls,
static unsigned int
webrtc_plugin_query_keepalive_factor (void *cls)
{
- return 3;
+ return 5;
}
@@ -270,8 +285,7 @@ static enum GNUNET_ATS_Network_Type
webrtc_plugin_get_network (void *cls,
struct GNUNET_ATS_Session *session)
{
- GNUNET_assert (NULL != session);
- return GNUNET_ATS_NET_UNSPECIFIED; /* Change to correct network type */
+ return GNUNET_ATS_NET_WAN;
}
@@ -286,7 +300,37 @@ static enum GNUNET_ATS_Network_Type
webrtc_plugin_get_network_for_address (void *cls,
const struct GNUNET_HELLO_Address *address)
{
- return GNUNET_ATS_NET_WAN; /* FOR NOW */
+ return GNUNET_ATS_NET_WAN;
+}
+
+
+/**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address. Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param cls closure
+ * @param addr binary address
+ * @param addrlen length of the address
+ * @return string representing the same address
+ */
+static const char *
+webrtc_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
+{
+ uint32_t options;
+ static char buf[7 + 10 + 1];
+
+ if (4 != addrlen)
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ _("Unexpected address length: %u bytes\n"),
+ (unsigned int) addrlen);
+ return NULL;
+ }
+ options = ntohl (*(uint32_t *)addr);
+ GNUNET_snprintf (buf, sizeof(buf), "webrtc.%u", options);
+ return buf;
}
@@ -312,7 +356,16 @@ webrtc_plugin_address_pretty_printer (void *cls, const char *type,
GNUNET_TRANSPORT_AddressStringCallback
asc, void *asc_cls)
{
- asc (asc_cls, "converted address", GNUNET_OK); /* return address */
+ const char *str = webrtc_plugin_address_to_string (cls, addr, addrlen);
+
+ if (NULL == str)
+ {
+ asc (asc_cls, NULL, GNUNET_SYSERR); /* invalid address */
+ }
+ else
+ {
+ asc (asc_cls, str, GNUNET_OK); /* return address */
+ }
asc (asc_cls, NULL, GNUNET_OK); /* done */
}
@@ -333,42 +386,11 @@ webrtc_plugin_address_pretty_printer (void *cls, const char *type,
static int
webrtc_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
{
- /* struct Plugin *plugin = cls; */
-
- /* check if the address is belonging to the plugin*/
return GNUNET_OK;
}
/**
- * Function called for a quick conversion of the binary address to
- * a numeric address. Note that the caller must not free the
- * address and that the next call to this function is allowed
- * to override the address again.
- *
- * @param cls closure
- * @param addr binary address
- * @param addrlen length of the address
- * @return string representing the same address
- */
-static const char *
-webrtc_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
-{
- /*
- * Print address in format webrtc.options.address
- */
-
- if (0 == addrlen)
- {
- return TRANSPORT_SESSION_INBOUND_STRING;
- }
-
- GNUNET_break (0);
- return NULL;
-}
-
-
-/**
* Function called to convert a string address to
* a binary address.
*
@@ -386,11 +408,118 @@ webrtc_plugin_string_to_address (void *cls,
uint16_t addrlen,
void **buf, size_t *added)
{
- /*
- * Parse string in format webrtc.options.address
- */
+ uint32_t options;
+ uint32_t *buf2;
+
+ if ((NULL == addr) || (0 == addrlen))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if ('\0' != addr[addrlen - 1])
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (strlen (addr) != addrlen - 1)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ addr = strchr (addr, '.');
+ if (NULL == addr)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ options = atol (addr);
+ buf2 = GNUNET_new (uint32_t);
+ *buf2 = htonl (options);
+ *buf = buf2;
+ *added = sizeof(*buf2);
+ return GNUNET_OK;
+}
+
+
+static void
+create_offer_cb(void *cls,
+ char *offer)
+{
+ struct GNUNET_ATS_Session *s = cls;
+ GNUNET_break (0);
+}
+
+
+/**
+ * Check if payload is sane (size contains payload).
+ *
+ * @param cls should match #ch
+ * @param message The actual message.
+ * @return #GNUNET_OK to keep the channel open,
+ * #GNUNET_SYSERR to close it (signal serious error).
+ */
+static int
+check_answer (void *cls,
+ const struct GNUNET_MessageHeader *message)
+{
+ return GNUNET_OK; /* all is well-formed */
+}
+
+
+/**
+ * Functions with this signature are called whenever a complete answer
+ * is received.
+ *
+ * @param cls closure
+ * @param srm the actual message
+ */
+static void
+handle_answer (void *cls,
+ const struct GNUNET_MessageHeader *message)
+{
+ struct GNUNET_ATS_Session *s = cls;
+ GNUNET_break (0);
+}
+
+
+/**
+ * Function called whenever an MQ-channel's transmission window size changes.
+ *
+ * The first callback in an outgoing channel will be with a non-zero value
+ * and will mean the channel is connected to the destination.
+ *
+ * For an incoming channel it will be called immediately after the
+ * #GNUNET_CADET_ConnectEventHandler, also with a non-zero value.
+ *
+ * @param cls Channel closure.
+ * @param channel Connection to the other end (henceforth invalid).
+ * @param window_size New window size. If the is more messages than buffer size
+ * this value will be negative..
+ */
+static void
+out_window_change_cb (void *cls,
+ const struct GNUNET_CADET_Channel *channel,
+ int window_size)
+{
+ /* FIXME: could do flow control here... */
+}
+
+
+/**
+ * Function called by cadet when a client disconnects.
+ * Cleans up our `struct CadetClient` of that channel.
+ *
+ * @param cls our `struct CadetClient`
+ * @param channel channel of the disconnecting client
+ * @param channel_ctx
+ */
+static void
+out_disconnect_cb (void *cls,
+ const struct GNUNET_CADET_Channel *channel)
+{
+ struct GNUNET_ATS_Session *s = cls;
+
GNUNET_break (0);
- return GNUNET_SYSERR;
}
@@ -407,7 +536,58 @@ static struct GNUNET_ATS_Session *
webrtc_plugin_get_session (void *cls,
const struct GNUNET_HELLO_Address *address)
{
- GNUNET_break (0);
+ struct Plugin *plugin = cls;
+ struct GNUNET_ATS_Session *s;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to get session for peer `%s'\n",
+ GNUNET_i2s (&address->peer));
+ /* find existing session */
+ s = GNUNET_CONTAINER_multipeermap_get (plugin->sessions,
+ &address->peer);
+ if (NULL != s)
+ return s;
+ s = GNUNET_new (struct GNUNET_ATS_Session);
+ s->plugin = plugin;
+ s->peer = address->peer;
+ /* add new session */
+ (void) GNUNET_CONTAINER_multipeermap_put (plugin->sessions,
+ &s->peer,
+ s,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_hd_var_size (answer,
+ MESSAGE_TYPE_WEBRTC_ANSWER,
+ struct GNUNET_MessageHeader,
+ plugin),
+ GNUNET_MQ_handler_end ()
+ };
+ s->channel = GNUNET_CADET_channel_create (plugin->cadet,
+ s,
+ &address->peer,
+ &plugin->port,
+ GNUNET_CADET_OPTION_RELIABLE,
+ out_window_change_cb,
+ out_disconnect_cb,
+ handlers);
+ GNUNET_assert (s->channel != NULL);
+
+ extern int create_connection(void *, void *);
+
+ s->rtc_peer_connection = create_connection(create_offer_cb, s);
+ /* Create RTCPeerConnection, call createOffer, when the returned promise is fulfilled, send it:
+ struct GNUNET_MessageHeader msg;
+ struct GNUNET_MQ_Envelope *env = GNUNET_MQ_msg (msg, MESSAGE_TYPE_WEBRTC_OFFER);
+
+ GNUNET_MQ_notify_sent (env,
+ &transmit_pending,
+ mh);
+ GNUNET_MQ_send (mq,
+ env);
+ */
+ notify_session_monitor (plugin,
+ s,
+ GNUNET_TRANSPORT_SS_INIT);
return NULL;
}
@@ -482,6 +662,95 @@ webrtc_plugin_setup_monitor (void *cls,
/**
+ * Check if payload is sane (size contains payload).
+ *
+ * @param cls should match #ch
+ * @param message The actual message.
+ * @return #GNUNET_OK to keep the channel open,
+ * #GNUNET_SYSERR to close it (signal serious error).
+ */
+static int
+check_offer (void *cls,
+ const struct GNUNET_MessageHeader *message)
+{
+ return GNUNET_OK; /* all is well-formed */
+}
+
+
+/**
+ * Functions with this signature are called whenever a complete offer
+ * is received.
+ *
+ * @param cls closure
+ * @param srm the actual message
+ */
+static void
+handle_offer (void *cls,
+ const struct GNUNET_MessageHeader *message)
+{
+ GNUNET_break (0);
+}
+
+
+/**
+ * Functions of this type are called upon new cadet connection from other peers.
+ *
+ * @param cls the closure from GNUNET_CADET_connect
+ * @param channel the channel representing the cadet
+ * @param initiator the identity of the peer who wants to establish a cadet
+ * with us; NULL on binding error
+ * @return initial channel context (our `struct CadetClient`)
+ */
+static void *
+connect_cb (void *cls,
+ struct GNUNET_CADET_Channel *channel,
+ const struct GNUNET_PeerIdentity *initiator)
+{
+ GNUNET_break (0);
+ return NULL;
+}
+
+
+/**
+ * Function called by cadet when a client disconnects.
+ * Cleans up our `struct CadetClient` of that channel.
+ *
+ * @param cls our `struct CadetClient`
+ * @param channel channel of the disconnecting client
+ * @param channel_ctx
+ */
+static void
+in_disconnect_cb (void *cls,
+ const struct GNUNET_CADET_Channel *channel)
+{
+ GNUNET_break (0);
+}
+
+
+/**
+ * Function called whenever an MQ-channel's transmission window size changes.
+ *
+ * The first callback in an outgoing channel will be with a non-zero value
+ * and will mean the channel is connected to the destination.
+ *
+ * For an incoming channel it will be called immediately after the
+ * #GNUNET_CADET_ConnectEventHandler, also with a non-zero value.
+ *
+ * @param cls Channel closure.
+ * @param channel Connection to the other end (henceforth invalid).
+ * @param window_size New window size. If the is more messages than buffer size
+ * this value will be negative..
+ */
+static void
+in_window_change_cb (void *cls,
+ const struct GNUNET_CADET_Channel *channel,
+ int window_size)
+{
+ /* FIXME: could do flow control here... */
+}
+
+
+/**
* Entry point for the plugin.
*/
void *
@@ -490,6 +759,7 @@ libgnunet_plugin_transport_webrtc_init (void *cls)
struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
struct GNUNET_TRANSPORT_PluginFunctions *api;
struct Plugin *plugin;
+ struct GNUNET_HELLO_Address *address;
if (NULL == env->receive)
{
@@ -505,6 +775,26 @@ libgnunet_plugin_transport_webrtc_init (void *cls)
plugin = GNUNET_new (struct Plugin);
plugin->env = env;
+ plugin->sessions = GNUNET_CONTAINER_multipeermap_create (128,
+ GNUNET_YES);
+ plugin->cadet = GNUNET_CADET_connect(env->cfg);
+ GNUNET_assert (plugin->cadet != NULL);
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_hd_var_size (offer,
+ MESSAGE_TYPE_WEBRTC_OFFER,
+ struct GNUNET_MessageHeader,
+ plugin),
+ GNUNET_MQ_handler_end ()
+ };
+ GNUNET_CRYPTO_hash ("webrtc", 6, &plugin->port);
+ plugin->in_port = GNUNET_CADET_open_port (plugin->cadet,
+ &plugin->port,
+ &connect_cb,
+ plugin,
+ &in_window_change_cb,
+ &in_disconnect_cb,
+ handlers);
+ GNUNET_assert (plugin->in_port != NULL);
api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions);
api->cls = plugin;
api->send = &webrtc_plugin_send;
@@ -520,7 +810,18 @@ libgnunet_plugin_transport_webrtc_init (void *cls)
api->get_network_for_address = &webrtc_plugin_get_network_for_address;
api->update_session_timeout = &webrtc_plugin_update_session_timeout;
api->setup_monitor = &webrtc_plugin_setup_monitor;
- LOG (GNUNET_ERROR_TYPE_INFO, "Template plugin successfully loaded\n");
+
+ uint32_t options = 0;
+ address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
+ PLUGIN_NAME,
+ &options,
+ sizeof (options),
+ GNUNET_HELLO_ADDRESS_INFO_NONE);
+ plugin->env->notify_address (plugin->env->cls,
+ GNUNET_YES,
+ address);
+ GNUNET_HELLO_address_free (address);
+ LOG (GNUNET_ERROR_TYPE_INFO, "WebRTC plugin successfully loaded\n");
return api;
}
@@ -534,6 +835,8 @@ libgnunet_plugin_transport_webrtc_done (void *cls)
struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
struct Plugin *plugin = api->cls;
+ GNUNET_CADET_close_port (plugin->in_port);
+ GNUNET_CADET_disconnect (plugin->cadet);
GNUNET_free (plugin);
GNUNET_free (api);
return NULL;
diff --git a/gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc_int.js b/gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc_int.js
index 8b114fa..33fd3c1 100644
--- a/gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc_int.js
+++ b/gnunet-build/packages/gnunet/gnunet/files/plugin_transport_webrtc_int.js
@@ -15,6 +15,34 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
mergeInto(LibraryManager.library, {
+ $RTC_CONFIG: {iceServers: [{url: "stun:stun.l.google.com:19302"}]},
+ $CONNECTIONS: [],
+ $NEXT_CONNECTION: 1,
+ create_connection__deps: ["$RTC_CONFIG", "$CONNECTIONS", "$NEXT_CONNECTION"],
+ create_connection: function(offer_cb, cls) {
+ var conn = new RTCPeerConnection(RTC_CONFIG);
+ chan = conn.createDataChannel("data", {ordered: false,
+ maxRetransmits: 0,
+ negotiated: true,
+ id: 1});
+ chan.onopen = function(e) {
+ console.warn("channel open");
+ };
+ chan.onmessage = function(e) {
+ console.warn("channel got message:", e);
+ };
+ offer = conn.createOffer();
+ offer.then(function(e) {
+ console.warn("created offer:", e);
+ ccallFunc(
+ getFuncWrapper(offer_cb, 'vii'),
+ 'void',
+ ['number', 'string'],
+ [cls, e.sdp]);
+ });
+ CONNECTIONS[NEXT_CONNECTION] = {conn: conn, chan: chan};
+ return NEXT_CONNECTION++;
+ }
});
-// vim: set expandtab ts=2 sw=2:
+// vim: set expandtab ts=2 sw=2: \ No newline at end of file