summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-09-25 11:18:03 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-09-26 08:36:40 +0200
commitb53fa04f47b54e08733ba3859bfaac171ab1c7af (patch)
tree1a28c4435e7d6ee95c18947af3b970945a5b61c6
parent7ef868e88b5e4807d2f88b4b122b9e129434182a (diff)
downloadcmumble-b53fa04f47b54e08733ba3859bfaac171ab1c7af.tar.gz
cmumble-b53fa04f47b54e08733ba3859bfaac171ab1c7af.tar.bz2
cmumble-b53fa04f47b54e08733ba3859bfaac171ab1c7af.zip
[WIP] Add support for transporting audio data using udp
-rw-r--r--src/cmumble.c35
-rw-r--r--src/cmumble.h6
-rw-r--r--src/connection.c136
-rw-r--r--src/connection.h9
4 files changed, 163 insertions, 23 deletions
diff --git a/src/cmumble.c b/src/cmumble.c
index 00e7afa..844a4d3 100644
--- a/src/cmumble.c
+++ b/src/cmumble.c
@@ -93,28 +93,19 @@ recv_server_sync(MumbleProto__ServerSync *sync, struct cmumble_context *ctx)
static void
recv_crypt_setup(MumbleProto__CryptSetup *crypt, struct cmumble_context *ctx)
{
-#if 0
- int i;
-
- if (crypt->has_key) {
- g_print("key: 0x");
- for (i = 0; i < crypt->key.len; ++i)
- g_print("%x", crypt->key.data[i]);
- g_print("\n");
- }
- if (crypt->has_client_nonce) {
- g_print("client nonce: 0x");
- for (i = 0; i < crypt->client_nonce.len; ++i)
- g_print("%x", crypt->client_nonce.data[i]);
- g_print("\n");
- }
- if (crypt->has_server_nonce) {
- g_print("server nonce: 0x");
- for (i = 0; i < crypt->server_nonce.len; ++i)
- g_print("%x", crypt->server_nonce.data[i]);
- g_print("\n");
- }
-#endif
+ /* FIXME: require all data lengths to be 16? */
+
+ ctx->ocb_key = g_memdup(crypt->key.data,
+ crypt->key.len);
+ ctx->ocb_client_nonce = g_memdup(crypt->client_nonce.data,
+ crypt->client_nonce.len);
+ ctx->ocb_server_nonce = g_memdup(crypt->server_nonce.data,
+ crypt->server_nonce.len);
+
+ ctx->ocb = ocb_aes_init(ctx->ocb_key, 16, NULL);
+ g_assert(ctx->ocb);
+
+ cmumble_connection_udp_init(ctx);
}
static void
diff --git a/src/cmumble.h b/src/cmumble.h
index 8caa9ef..9e65ec2 100644
--- a/src/cmumble.h
+++ b/src/cmumble.h
@@ -11,6 +11,7 @@
#include "connection.h"
#include "audio.h"
#include "commands.h"
+#include "ocb/ocb.h"
typedef void (*callback_t)(ProtobufCMessage *msg, struct cmumble_context *);
@@ -32,6 +33,11 @@ struct cmumble_context {
GList *users;
GList *channels;
+
+ keystruct *ocb;
+ guchar *ocb_key;
+ guchar *ocb_client_nonce;
+ guchar *ocb_server_nonce;
};
struct cmumble_user {
diff --git a/src/connection.c b/src/connection.c
index c93dbc7..66b2cdd 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -3,6 +3,7 @@
#include "connection.h"
#include "cmumble.h"
+#include "varint.h"
static gboolean
read_cb(GObject *pollable_stream, gpointer data)
@@ -18,6 +19,140 @@ read_cb(GObject *pollable_stream, gpointer data)
return TRUE;
}
+static gboolean
+read_udp(GSocket *socket, GIOCondition condition, gpointer user_data)
+{
+ GError *error = NULL;
+ gchar buf[1024];
+ gssize size;
+
+ size = g_socket_receive(socket, buf, sizeof(buf), NULL, &error);
+
+ g_print("got udp data: %ld\n", size);
+
+ return TRUE;
+}
+
+static gboolean
+read_udp_io(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ g_print("got udp data from channel\n");
+
+ return TRUE;
+}
+
+static void
+print_hex(char *hex, int num)
+{
+ int i;
+
+ for (i = 0; i < num; ++i)
+ printf("%02x", hex[i] & 0xff);
+
+}
+
+static void
+do_udp_ping(struct cmumble_context *ctx)
+{
+ uint8_t data[16];
+ uint32_t write = 0, pos = 0;
+ GTimeVal tv;
+ GError *error = NULL;
+ gssize sent;
+ int i;
+
+ g_get_current_time(&tv);
+
+ data[pos++] = (udp_ping << 5);
+ encode_varint(&data[pos], &write, tv.tv_sec, 16-pos);
+ pos += write;
+ g_print("write: %d\n", write);
+
+ char tag[16] = { 0 };
+ char foo[16] = { 0 };
+
+ /* Increase nonce, see:
+ * http://www.cs.ucdavis.edu/~rogaway/ocb/ocb-back.htm#nonce */
+ for (i = 0; i < 16; ++i)
+ if (++ctx->ocb_client_nonce[i])
+ break;
+
+ ocb_aes_encrypt(ctx->ocb, ctx->ocb_client_nonce,
+ data, pos,
+ foo+4, tag);
+
+ printf("\n");
+ printf("nonce: 0x");
+ print_hex(ctx->ocb_client_nonce, 16);
+ printf("\n");
+
+ printf("tag: 0x");
+ print_hex(tag, 3);
+ printf("\n");
+
+ printf("data: 0x");
+ print_hex((char *)data, pos);
+ printf("\n");
+
+ printf("foo: 0x");
+ print_hex(foo, pos+4);
+ printf("\n");
+
+ //memset(tag, 0, 128);
+
+#if 0
+ ocb_aes_decrypt(ctx->ocb, ctx->ocb_client_nonce,
+ foo+4, pos,
+ bar, tag);
+
+ printf("decrypt: 0x");
+ print_hex(bar, pos);
+ printf("\n");
+#endif
+
+ foo[0] = ctx->ocb_client_nonce[0];
+ foo[1] = tag[0];
+ foo[2] = tag[1];
+ foo[3] = tag[2];
+
+ sent = g_socket_send(ctx->con.udp.sock, foo, pos+4, NULL, &error);
+
+ g_print("udp sent: %ld\n", sent);
+}
+
+void
+cmumble_connection_udp_init(struct cmumble_context *ctx)
+{
+ GError *error = NULL;
+
+ ctx->con.udp.connected = FALSE;
+ ctx->con.udp.sock = g_socket_new(G_SOCKET_FAMILY_IPV4,
+ G_SOCKET_TYPE_DATAGRAM,
+ G_SOCKET_PROTOCOL_UDP,
+ &error);
+ g_assert(error == NULL);
+
+ GInetAddress *addr = g_inet_address_new_from_string("192.168.2.232");
+ g_assert(addr);
+ GSocketAddress *saddr = g_inet_socket_address_new(addr, 64738);
+
+ if (!g_socket_connect(ctx->con.udp.sock, saddr, NULL, &error))
+ return;
+
+ ctx->con.udp.connected = TRUE;
+ ctx->con.udp.source = g_socket_create_source(ctx->con.udp.sock, G_IO_IN, NULL);
+ g_source_set_callback(ctx->con.udp.source, (GSourceFunc) read_udp, ctx, NULL);
+ g_source_attach(ctx->con.udp.source, NULL);
+
+ int fd = g_socket_get_fd(ctx->con.udp.sock);
+ GIOChannel* channel = g_io_channel_unix_new(fd);
+ g_io_add_watch(channel, G_IO_IN,
+ (GIOFunc) read_udp_io, ctx);
+ g_io_channel_unref(channel);
+
+ do_udp_ping(ctx);
+}
+
static void
connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
@@ -48,7 +183,6 @@ connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data)
con->source = g_pollable_input_stream_create_source(con->input, NULL);
g_source_set_callback(con->source, (GSourceFunc) read_cb, ctx, NULL);
g_source_attach(con->source, NULL);
- g_source_unref(con->source);
cmumble_protocol_init(ctx);
}
diff --git a/src/connection.h b/src/connection.h
index f37c0c7..2b9a97f 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -12,6 +12,12 @@ struct cmumble_connection {
GOutputStream *output;
GSource *source;
+
+ struct {
+ GSocket *sock;
+ gboolean connected;
+ GSource *source;
+ } udp;
};
struct cmumble_context;
@@ -23,4 +29,7 @@ cmumble_connection_init(struct cmumble_context *ctx,
int
cmumble_connection_fini(struct cmumble_context *ctx);
+void
+cmumble_connection_udp_init(struct cmumble_context *ctx);
+
#endif /* _CONNECTION_H_ */