tests/test-pseudotcp
tests/test-pseudotcp-fuzzy
tests/test-restart
+tests/test-tcp
tests/test-thread
tests/test-new-dribble
udp-bsd.c \
tcp-bsd.h \
tcp-bsd.c \
+ tcp-active.h \
+ tcp-active.c \
+ tcp-passive.h \
+ tcp-passive.c \
pseudossl.h \
pseudossl.c \
socks5.h \
#include "udp-bsd.h"
#include "tcp-bsd.h"
+#include "tcp-active.h"
+#include "tcp-passive.h"
#include "pseudossl.h"
#include "socks5.h"
#include "http.h"
--- /dev/null
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2008-2012 Collabora Ltd.
+ * Contact: Youness Alaoui
+ * (C) 2008-2009 Nokia Corporation. All rights reserved.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ * Youness Alaoui, Collabora Ltd.
+ * George Kiagiadakis, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "socket.h"
+#include "tcp-active.h"
+
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifndef G_OS_WIN32
+#include <unistd.h>
+#endif
+
+typedef struct {
+ GSocketAddress *local_addr;
+ GMainContext *context;
+} TcpActivePriv;
+
+
+static void socket_close (NiceSocket *sock);
+static gint socket_recv_messages (NiceSocket *sock,
+ NiceInputMessage *recv_messages, guint n_recv_messages);
+static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
+ const NiceOutputMessage *messages, guint n_messages);
+static gint socket_send_messages_reliable (NiceSocket *sock,
+ const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
+static gboolean socket_is_reliable (NiceSocket *sock);
+
+
+NiceSocket *
+nice_tcp_active_socket_new (GMainContext *ctx, NiceAddress *addr)
+{
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr addr;
+ } name;
+ NiceSocket *sock;
+ TcpActivePriv *priv;
+ GSocketAddress *gaddr;
+ NiceAddress local_addr;
+
+ if (addr != NULL) {
+
+ local_addr = *addr;
+ /* Make sure we don't bind to any local port */
+ nice_address_set_port (&local_addr, 0);
+ nice_address_copy_to_sockaddr(&local_addr, &name.addr);
+ } else {
+ memset (&local_addr, 0, sizeof (local_addr));
+ memset (&name, 0, sizeof (name));
+ name.storage.ss_family = AF_UNSPEC;
+ }
+
+ gaddr = g_socket_address_new_from_native (&name, sizeof (name));
+
+ if (gaddr == NULL) {
+ return NULL;
+ }
+
+ sock = g_slice_new0 (NiceSocket);
+
+ sock->priv = priv = g_slice_new0 (TcpActivePriv);
+
+ priv->context = g_main_context_ref (ctx);
+ priv->local_addr = gaddr;
+
+ sock->type = NICE_SOCKET_TYPE_TCP_ACTIVE;
+ sock->fileno = NULL;
+ sock->addr = local_addr;
+ sock->send_messages = socket_send_messages;
+ sock->send_messages_reliable = socket_send_messages_reliable;
+ sock->recv_messages = socket_recv_messages;
+ sock->is_reliable = socket_is_reliable;
+ sock->close = socket_close;
+
+ return sock;
+}
+
+static void
+socket_close (NiceSocket *sock)
+{
+ TcpActivePriv *priv = sock->priv;
+
+ if (priv->context)
+ g_main_context_unref (priv->context);
+ if (priv->local_addr)
+ g_object_unref (priv->local_addr);
+
+ g_slice_free(TcpActivePriv, sock->priv);
+}
+
+static gint socket_recv_messages (NiceSocket *sock,
+ NiceInputMessage *recv_messages, guint n_recv_messages)
+{
+ return -1;
+}
+
+static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
+ const NiceOutputMessage *messages, guint n_messages)
+{
+ return -1;
+}
+
+static gint socket_send_messages_reliable (NiceSocket *sock,
+ const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages)
+{
+ return -1;
+}
+
+static gboolean
+socket_is_reliable (NiceSocket *sock)
+{
+ return TRUE;
+}
+
+NiceSocket *
+nice_tcp_active_socket_connect (NiceSocket *sock, NiceAddress *addr)
+{
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr addr;
+ } name;
+ TcpActivePriv *priv = sock->priv;
+ GSocket *gsock = NULL;
+ GError *gerr = NULL;
+ gboolean gret = FALSE;
+ GSocketAddress *gaddr;
+ NiceAddress local_addr;
+ NiceSocket *new_socket = NULL;
+
+ if (addr == NULL) {
+ /* We can't connect a tcp socket with no destination address */
+ return NULL;
+ }
+
+ nice_address_copy_to_sockaddr (addr, &name.addr);
+
+ if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) {
+ gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_TCP, NULL);
+
+ name.storage.ss_family = AF_INET;
+#ifdef HAVE_SA_LEN
+ name.storage.ss_len = sizeof (struct sockaddr_in);
+#endif
+ } else if (name.storage.ss_family == AF_INET6) {
+ gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_TCP, NULL);
+ name.storage.ss_family = AF_INET6;
+#ifdef HAVE_SA_LEN
+ name.storage.ss_len = sizeof (struct sockaddr_in6);
+#endif
+ }
+
+ if (gsock == NULL) {
+ return NULL;
+ }
+
+ gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name));
+ if (gaddr == NULL) {
+ g_object_unref (gsock);
+ return NULL;
+ }
+
+ /* GSocket: All socket file descriptors are set to be close-on-exec. */
+ g_socket_set_blocking (gsock, false);
+
+ /* Allow g_socket_bind to fail */
+ g_socket_bind (gsock, priv->local_addr, FALSE, NULL);
+
+ gret = g_socket_connect (gsock, gaddr, NULL, &gerr);
+ g_object_unref (gaddr);
+
+ if (gret == FALSE) {
+ if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_PENDING) == FALSE) {
+ g_error_free (gerr);
+ g_socket_close (gsock, NULL);
+ g_object_unref (gsock);
+ return NULL;
+ }
+ g_error_free (gerr);
+ }
+
+ gaddr = g_socket_get_local_address (gsock, NULL);
+ if (gaddr == NULL ||
+ !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) {
+ g_socket_close (gsock, NULL);
+ g_object_unref (gsock);
+ return NULL;
+ }
+ g_object_unref (gaddr);
+
+ nice_address_set_from_sockaddr (&local_addr, &name.addr);
+
+ new_socket = nice_tcp_bsd_socket_new_from_gsock (priv->context, gsock,
+ &local_addr, addr, TRUE);
+ g_object_unref (gsock);
+
+ return new_socket;
+}
--- /dev/null
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2008-2009 Collabora Ltd.
+ * Contact: Youness Alaoui
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ * Youness Alaoui, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+
+#ifndef _TCP_ACTIVE_H
+#define _TCP_ACTIVE_H
+
+#include "socket.h"
+
+G_BEGIN_DECLS
+
+
+NiceSocket * nice_tcp_active_socket_new (GMainContext *ctx, NiceAddress *addr);
+NiceSocket * nice_tcp_active_socket_connect (NiceSocket *socket, NiceAddress *addr);
+
+
+G_END_DECLS
+
+#endif /* _TCP_ACTIVE_H */
+
--- /dev/null
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2008-2012 Collabora Ltd.
+ * Contact: Youness Alaoui
+ * (C) 2008-2009 Nokia Corporation. All rights reserved.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ * Youness Alaoui, Collabora Ltd.
+ * George Kiagiadakis, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "tcp-passive.h"
+#include "agent-priv.h"
+
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifndef G_OS_WIN32
+#include <unistd.h>
+#endif
+
+typedef struct {
+ GMainContext *context;
+} TcpPassivePriv;
+
+
+static void socket_close (NiceSocket *sock);
+static gint socket_recv_messages (NiceSocket *sock,
+ NiceInputMessage *recv_messages, guint n_recv_messages);
+static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
+ const NiceOutputMessage *messages, guint n_messages);
+static gint socket_send_messages_reliable (NiceSocket *sock,
+ const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
+static gboolean socket_is_reliable (NiceSocket *sock);
+
+
+NiceSocket *
+nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr)
+{
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr addr;
+ } name;
+ NiceSocket *sock;
+ TcpPassivePriv *priv;
+ GSocket *gsock = NULL;
+ gboolean gret = FALSE;
+ GSocketAddress *gaddr;
+
+ if (addr != NULL) {
+ nice_address_copy_to_sockaddr(addr, &name.addr);
+ } else {
+ memset (&name, 0, sizeof (name));
+ name.storage.ss_family = AF_UNSPEC;
+ }
+
+ if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) {
+ gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_TCP, NULL);
+
+ name.storage.ss_family = AF_INET;
+#ifdef HAVE_SA_LEN
+ name.storage.ss_len = sizeof (struct sockaddr_in);
+#endif
+ } else if (name.storage.ss_family == AF_INET6) {
+ gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_TCP, NULL);
+ name.storage.ss_family = AF_INET6;
+#ifdef HAVE_SA_LEN
+ name.storage.ss_len = sizeof (struct sockaddr_in6);
+#endif
+ }
+
+ if (gsock == NULL) {
+ return NULL;
+ }
+
+ gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name));
+
+ if (gaddr == NULL) {
+ g_object_unref (gsock);
+ return NULL;
+ }
+
+ /* GSocket: All socket file descriptors are set to be close-on-exec. */
+ g_socket_set_blocking (gsock, false);
+
+ gret = g_socket_bind (gsock, gaddr, FALSE, NULL) &&
+ g_socket_listen (gsock, NULL);
+ g_object_unref (gaddr);
+
+ if (gret == FALSE) {
+ g_socket_close (gsock, NULL);
+ g_object_unref (gsock);
+ return NULL;
+ }
+
+ gaddr = g_socket_get_local_address (gsock, NULL);
+ if (gaddr == NULL ||
+ !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) {
+ g_socket_close (gsock, NULL);
+ g_object_unref (gsock);
+ return NULL;
+ }
+ g_object_unref (gaddr);
+
+ sock = g_slice_new0 (NiceSocket);
+
+ nice_address_set_from_sockaddr (&sock->addr, &name.addr);
+
+ sock->priv = priv = g_slice_new0 (TcpPassivePriv);
+ priv->context = g_main_context_ref (ctx);
+
+ sock->type = NICE_SOCKET_TYPE_TCP_PASSIVE;
+ sock->fileno = gsock;
+ sock->send_messages = socket_send_messages;
+ sock->send_messages_reliable = socket_send_messages_reliable;
+ sock->recv_messages = socket_recv_messages;
+ sock->is_reliable = socket_is_reliable;
+ sock->close = socket_close;
+
+ return sock;
+}
+
+static void
+socket_close (NiceSocket *sock)
+{
+ TcpPassivePriv *priv = sock->priv;
+
+ if (priv->context)
+ g_main_context_unref (priv->context);
+
+ g_slice_free (TcpPassivePriv, sock->priv);
+}
+
+static gint socket_recv_messages (NiceSocket *sock,
+ NiceInputMessage *recv_messages, guint n_recv_messages)
+{
+ return -1;
+}
+
+static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
+ const NiceOutputMessage *messages, guint n_messages)
+{
+ return -1;
+}
+
+static gint socket_send_messages_reliable (NiceSocket *sock,
+ const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages)
+{
+ return -1;
+}
+
+static gboolean
+socket_is_reliable (NiceSocket *sock)
+{
+ return TRUE;
+}
+
+NiceSocket *
+nice_tcp_passive_socket_accept (NiceSocket *sock)
+{
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr addr;
+ } name;
+ TcpPassivePriv *priv = sock->priv;
+ GSocket *gsock = NULL;
+ GSocketAddress *gaddr;
+ NiceAddress remote_addr;
+ NiceSocket *new_socket = NULL;
+
+ gsock = g_socket_accept (sock->fileno, NULL, NULL);
+
+ if (gsock == NULL) {
+ return NULL;
+ }
+
+ /* GSocket: All socket file descriptors are set to be close-on-exec. */
+ g_socket_set_blocking (gsock, false);
+
+ gaddr = g_socket_get_remote_address (gsock, NULL);
+ if (gaddr == NULL ||
+ !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) {
+ g_socket_close (gsock, NULL);
+ g_object_unref (gsock);
+ return NULL;
+ }
+ g_object_unref (gaddr);
+
+ nice_address_set_from_sockaddr (&remote_addr, &name.addr);
+
+ new_socket = nice_tcp_bsd_socket_new_from_gsock (priv->context, gsock,
+ &sock->addr, &remote_addr, TRUE);
+ g_object_unref (gsock);
+
+ return new_socket;
+}
--- /dev/null
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2008-2012 Collabora Ltd.
+ * Contact: Youness Alaoui
+ * (C) 2008-2009 Nokia Corporation. All rights reserved.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ * Youness Alaoui, Collabora Ltd.
+ * George Kiagiadakis, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+
+#ifndef _TCP_PASSIVE_H
+#define _TCP_PASSIVE_H
+
+#include "socket.h"
+
+G_BEGIN_DECLS
+
+
+NiceSocket * nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr);
+NiceSocket * nice_tcp_passive_socket_accept (NiceSocket *socket);
+
+
+G_END_DECLS
+
+#endif /* _TCP_PASSIVE_H */
+
test-fallback \
test-thread \
test-dribble \
- test-new-dribble
+ test-new-dribble \
+ test-tcp
dist_check_SCRIPTS = \
check-test-fullmode-with-stun.sh \
test_new_dribble_LDADD = $(COMMON_LDADD)
+test_tcp_LDADD = $(COMMON_LDADD)
+
all-local:
chmod a+x $(srcdir)/check-test-fullmode-with-stun.sh
chmod a+x $(srcdir)/test-pseudotcp-random.sh
--- /dev/null
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2012 Collabora Ltd.
+ * Contact: George Kiagiadakis
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ * George Kiagiadakis, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+#include "socket.h"
+
+GMainLoop *mainloop = NULL;
+NiceSocket *active_sock, *client;
+NiceSocket *passive_sock, *server;
+NiceAddress tmp;
+gchar buf[5];
+
+static gboolean
+on_server_connection_available (gpointer user_data)
+{
+ server = nice_tcp_passive_socket_accept (passive_sock);
+ g_assert (server);
+ nice_socket_free (passive_sock);
+ passive_sock = NULL;
+
+ g_main_loop_quit (mainloop);
+
+ return FALSE;
+}
+
+static gboolean
+on_server_input_available (gpointer user_data)
+{
+ g_assert (5 == nice_socket_recv (server, &tmp, 5, buf));
+ g_assert (nice_address_equal (&tmp, &client->addr));
+
+ g_main_loop_quit (mainloop);
+
+ return FALSE;
+}
+
+static gboolean
+on_client_input_available (gpointer user_data)
+{
+ g_assert (5 == nice_socket_recv (client, &tmp, 5, buf));
+ g_assert (nice_address_equal (&tmp, &server->addr));
+
+ g_main_loop_quit (mainloop);
+
+ return FALSE;
+}
+
+int
+main (void)
+{
+ NiceAddress active_bind_addr, passive_bind_addr;
+ GSource *srv_listen_source, *srv_input_source, *cli_input_source;
+
+ g_type_init ();
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ nice_address_init (&active_bind_addr);
+ g_assert (nice_address_set_from_string (&active_bind_addr, "::1"));
+
+ nice_address_init (&passive_bind_addr);
+ g_assert (nice_address_set_from_string (&passive_bind_addr, "::1"));
+ nice_address_set_port (&passive_bind_addr, 23456);
+
+ nice_address_init (&tmp);
+
+ passive_sock = nice_tcp_passive_socket_new (g_main_loop_get_context (mainloop),
+ &passive_bind_addr);
+ g_assert (passive_sock);
+
+ srv_listen_source = g_socket_create_source (passive_sock->fileno,
+ G_IO_IN, NULL);
+ g_source_set_callback (srv_listen_source,
+ on_server_connection_available, NULL, NULL);
+ g_source_attach (srv_listen_source, g_main_loop_get_context (mainloop));
+
+ active_sock = nice_tcp_active_socket_new (g_main_loop_get_context (mainloop),
+ &active_bind_addr);
+ g_assert (active_sock);
+
+ client = nice_tcp_active_socket_connect (active_sock, &passive_bind_addr);
+ g_assert (client);
+ nice_socket_free (active_sock);
+ active_sock = NULL;
+
+ g_main_loop_run (mainloop); /* -> on_server_connection_available */
+ g_assert (server);
+
+ srv_input_source = g_socket_create_source (server->fileno, G_IO_IN, NULL);
+ g_source_set_callback (srv_input_source,
+ on_server_input_available, NULL, NULL);
+ g_source_attach (srv_input_source, g_main_loop_get_context (mainloop));
+
+ cli_input_source = g_socket_create_source (client->fileno, G_IO_IN, NULL);
+ g_source_set_callback (cli_input_source,
+ on_client_input_available, NULL, NULL);
+ g_source_attach (cli_input_source, g_main_loop_get_context (mainloop));
+
+ g_assert (nice_address_get_port (&client->addr) != 0);
+ g_assert (nice_address_get_port (&server->addr) == 23456);
+
+ g_assert (nice_address_set_from_string (&tmp, "::1"));
+ nice_address_set_port (&tmp, nice_address_get_port (&server->addr));
+ g_assert (nice_address_get_port (&tmp) != 0);
+
+
+ g_assert (5 == nice_socket_send (client, &tmp, 5, "hello"));
+ g_main_loop_run (mainloop); /* -> on_server_input_available */
+ g_assert (0 == strncmp (buf, "hello", 5));
+
+ g_assert (5 == nice_socket_send (server, &tmp, 5, "uryyb"));
+ g_main_loop_run (mainloop); /* -> on_client_input_available */
+ g_assert (0 == strncmp (buf, "uryyb", 5));
+
+ nice_socket_free (client);
+ nice_socket_free (server);
+
+ g_source_unref (srv_listen_source);
+ g_source_unref (srv_input_source);
+ g_source_unref (cli_input_source);
+ g_main_loop_unref (mainloop);
+
+ return 0;
+}