diff --git a/linux_x86/include/nice/address.h b/linux_x86/include/nice/address.h new file mode 100644 index 0000000..fa555b2 --- /dev/null +++ b/linux_x86/include/nice/address.h @@ -0,0 +1,307 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2006-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2006-2009 Nokia Corporation. All rights reserved. + * Contact: Kai Vehmanen + * + * 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. + * Dafydd Harries, Collabora Ltd. + * Kai Vehmanen + * + * 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 __LIBNICE_ADDRESS_H__ +#define __LIBNICE_ADDRESS_H__ + +/** + * SECTION:address + * @short_description: IP address convenience library + * @stability: Stable + * + * The #NiceAddress structure will allow you to easily set/get and modify an IPv4 + * or IPv6 address in order to communicate with the #NiceAgent. + */ + + +#include + +#ifdef G_OS_WIN32 +#include +#include +#else +#include +#include +#include +#include +#endif + +G_BEGIN_DECLS + + +/** + * NiceAddress: + * + * The #NiceAddress structure that represents an IPv4 or IPv6 address. + */ +struct _NiceAddress +{ + union + { + struct sockaddr addr; + struct sockaddr_in ip4; + struct sockaddr_in6 ip6; + } s; +}; + + +/** + * NICE_ADDRESS_STRING_LEN: + * + * The maximum string length representation of an address. + * When using nice_address_to_string() make sure the string has a size of + * at least %NICE_ADDRESS_STRING_LEN + */ +#define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN + +typedef struct _NiceAddress NiceAddress; + + +/** + * nice_address_init: + * @addr: The #NiceAddress to init + * + * Initialize a #NiceAddress into an undefined address + */ +void +nice_address_init (NiceAddress *addr); + +/** + * nice_address_new: + * + * Create a new #NiceAddress with undefined address + * You must free it with nice_address_free() + * + * Returns: The new #NiceAddress + */ +NiceAddress * +nice_address_new (void); + +/** + * nice_address_free: + * @addr: The #NiceAddress to free + * + * Frees a #NiceAddress created with nice_address_new() or nice_address_dup() + */ +void +nice_address_free (NiceAddress *addr); + +/** + * nice_address_dup: + * @addr: The #NiceAddress to dup + * + * Creates a new #NiceAddress with the same address as @addr + * + * Returns: The new #NiceAddress + */ +NiceAddress * +nice_address_dup (const NiceAddress *addr); + + +/** + * nice_address_set_ipv4: + * @addr: The #NiceAddress to modify + * @addr_ipv4: The IPv4 address + * + * Set @addr to an IPv4 address using the data from @addr_ipv4 + * + + + This function will reset the port to 0, so make sure you call it before + nice_address_set_port() + + + */ +void +nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4); + + +/** + * nice_address_set_ipv6: + * @addr: The #NiceAddress to modify + * @addr_ipv6: The IPv6 address + * + * Set @addr to an IPv6 address using the data from @addr_ipv6 + * + + + This function will reset the port to 0, so make sure you call it before + nice_address_set_port() + + + */ +void +nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6); + + +/** + * nice_address_set_port: + * @addr: The #NiceAddress to modify + * @port: The port to set + * + * Set the port of @addr to @port + */ +void +nice_address_set_port (NiceAddress *addr, guint port); + +/** + * nice_address_get_port: + * @addr: The #NiceAddress to query + * + * Retreive the port of @addr + * + * Returns: The port of @addr + */ +guint +nice_address_get_port (const NiceAddress *addr); + +/** + * nice_address_set_from_string: + * @addr: The #NiceAddress to modify + * @str: The string to set + * + * Sets an IPv4 or IPv6 address from the string @str + * + * Returns: %TRUE if success, %FALSE on error + */ +gboolean +nice_address_set_from_string (NiceAddress *addr, const gchar *str); + +/** + * nice_address_set_from_sockaddr: + * @addr: The #NiceAddress to modify + * @sin: The sockaddr to set + * + * Sets an IPv4 or IPv6 address from the sockaddr structure @sin + * + */ +void +nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin); + + +/** + * nice_address_copy_to_sockaddr: + * @addr: The #NiceAddress to query + * @sin: The sockaddr to fill + * + * Fills the sockaddr structure @sin with the address contained in @addr + * + */ +void +nice_address_copy_to_sockaddr (const NiceAddress *addr, struct sockaddr *sin); + +/** + * nice_address_equal: + * @a: First #NiceAddress to compare + * @b: Second #NiceAddress to compare + * + * Compares two #NiceAddress structures to see if they contain the same address + * and the same port. + * + * Returns: %TRUE if @a and @b are the same address, %FALSE if they are different + */ +gboolean +nice_address_equal (const NiceAddress *a, const NiceAddress *b); + +/** + * nice_address_equal_no_port: + * @a: First #NiceAddress to compare + * @b: Second #NiceAddress to compare + * + * Compares two #NiceAddress structures to see if they contain the same address, + * ignoring the port. + * + * Returns: %TRUE if @a and @b are the same address, %FALSE if they + * are different + * + * Since: 0.1.8 + */ +gboolean +nice_address_equal_no_port (const NiceAddress *a, const NiceAddress *b); + +/** + * nice_address_to_string: + * @addr: The #NiceAddress to query + * @dst: The string to fill + * + * Transforms the address @addr into a human readable string + * + */ +void +nice_address_to_string (const NiceAddress *addr, gchar *dst); + +/** + * nice_address_is_private: + * @addr: The #NiceAddress to query + * + * Verifies if the address in @addr is a private address or not + * + * Returns: %TRUE if @addr is a private address, %FALSE otherwise + */ +gboolean +nice_address_is_private (const NiceAddress *addr); + +/** + * nice_address_is_valid: + * @addr: The #NiceAddress to query + * + * Validate whether the #NiceAddress @addr is a valid IPv4 or IPv6 address + * + * Returns: %TRUE if @addr is valid, %FALSE otherwise + */ +G_GNUC_WARN_UNUSED_RESULT +gboolean +nice_address_is_valid (const NiceAddress *addr); + +/** + * nice_address_ip_version: + * @addr: The #NiceAddress to query + * + * Returns the IP version of the address + * + * Returns: 4 for IPv4, 6 for IPv6 and 0 for undefined address + */ +G_GNUC_WARN_UNUSED_RESULT +int +nice_address_ip_version (const NiceAddress *addr); + +G_END_DECLS + +#endif /* __LIBNICE_ADDRESS_H__ */ + diff --git a/linux_x86/include/nice/agent.h b/linux_x86/include/nice/agent.h new file mode 100644 index 0000000..1164138 --- /dev/null +++ b/linux_x86/include/nice/agent.h @@ -0,0 +1,1709 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2006-2010 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2006-2010 Nokia Corporation. All rights reserved. + * Contact: Kai Vehmanen + * + * 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: + * Dafydd Harries, Collabora Ltd. + * Youness Alaoui, Collabora Ltd. + * Kai Vehmanen, Nokia + * + * 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 __LIBNICE_AGENT_H__ +#define __LIBNICE_AGENT_H__ + +/** + * SECTION:agent + * @short_description: ICE agent API implementation + * @see_also: #NiceCandidate, #NiceAddress + * @include: agent.h + * @stability: Stable + * + * The #NiceAgent is your main object when using libnice. + * It is the agent that will take care of everything relating to ICE. + * It will take care of discovering your local candidates and do + * connectivity checks to create a stream of data between you and your peer. + * + * A #NiceAgent must always be used with a #GMainLoop running the #GMainContext + * passed into nice_agent_new() (or nice_agent_new_reliable()). Without the + * #GMainContext being iterated, the agent’s timers will not fire, etc. + * + * Streams and their components are referenced by integer IDs (with respect to a + * given #NiceAgent). These IDs are guaranteed to be positive (i.e. non-zero) + * for valid streams/components. + * + * To complete the ICE connectivity checks, the user must either register + * an I/O callback (with nice_agent_attach_recv()) or call nice_agent_recv_messages() + * in a loop on a dedicated thread. + * Technically, #NiceAgent does not poll the streams on its own, since + * user data could arrive at any time; to receive STUN packets + * required for establishing ICE connectivity, it is backpiggying + * on the facility chosen by the user. #NiceAgent will handle all STUN + * packets internally; they're never actually passed to the I/O callback + * or returned from nice_agent_recv_messages() and related functions. + * + * Each stream can receive data in one of two ways: using + * nice_agent_attach_recv() or nice_agent_recv_messages() (and the derived + * #NiceInputStream and #NiceIOStream classes accessible using + * nice_agent_get_io_stream()). nice_agent_attach_recv() is non-blocking: it + * takes a user-provided callback function and attaches the stream’s socket to + * the provided #GMainContext, invoking the callback in that context for every + * packet received. nice_agent_recv_messages() instead blocks on receiving a + * packet, and writes it directly into a user-provided buffer. This reduces the + * number of callback invokations and (potentially) buffer copies required to + * receive packets. nice_agent_recv_messages() (or #NiceInputStream) is designed + * to be used in a blocking loop in a separate thread. + * + * + * Simple example on how to use libnice + * + * guint stream_id; + * gchar buffer[] = "hello world!"; + * gchar *ufrag = NULL, *pwd = NULL; + * gchar *remote_ufrag, *remote_pwd; + * GSList *lcands = NULL; + * + * // Create a nice agent, passing in the global default GMainContext. + * NiceAgent *agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); + * spawn_thread_to_run_main_loop (g_main_loop_new (NULL, FALSE)); + * + * // Connect the signals + * g_signal_connect (G_OBJECT (agent), "candidate-gathering-done", + * G_CALLBACK (cb_candidate_gathering_done), NULL); + * g_signal_connect (G_OBJECT (agent), "component-state-changed", + * G_CALLBACK (cb_component_state_changed), NULL); + * g_signal_connect (G_OBJECT (agent), "new-selected-pair", + * G_CALLBACK (cb_new_selected_pair), NULL); + * + * // Create a new stream with one component and start gathering candidates + * stream_id = nice_agent_add_stream (agent, 1); + * nice_agent_gather_candidates (agent, stream_id); + * + * // Attach I/O callback the component to ensure that: + * // 1) agent gets its STUN packets (not delivered to cb_nice_recv) + * // 2) you get your own data + * nice_agent_attach_recv (agent, stream_id, 1, NULL, + * cb_nice_recv, NULL); + * + * // ... Wait until the signal candidate-gathering-done is fired ... + * lcands = nice_agent_get_local_candidates(agent, stream_id, 1); + + * nice_agent_get_local_credentials(agent, stream_id, &ufrag, &pwd); + * + * // ... Send local candidates and credentials to the peer + * + * // Set the peer's remote credentials and remote candidates + * nice_agent_set_remote_credentials (agent, stream_id, remote_ufrag, remote_pwd); + * nice_agent_set_remote_candidates (agent, stream_id, 1, rcands); + * + * // ... Wait until the signal new-selected-pair is fired ... + * // Send our message! + * nice_agent_send (agent, stream_id, 1, sizeof(buffer), buffer); + * + * // Anything received will be received through the cb_nice_recv callback. + * // You must be running a GMainLoop on the global default GMainContext in + * // another thread for this to work. + * + * // Destroy the object + * g_object_unref(agent); + * + * + * + * + * Refer to the examples in the examples/ subdirectory of the libnice source for + * more complete examples. + * + */ + + +#include +#include + +/** + * NiceAgent: + * + * The #NiceAgent is the main GObject of the libnice library and represents + * the ICE agent. + */ +typedef struct _NiceAgent NiceAgent; + +#include "address.h" +#include "candidate.h" +#include "debug.h" + + +G_BEGIN_DECLS + +/** + * NiceInputMessage: + * @buffers: (array length=n_buffers): unowned array of #GInputVector buffers to + * store data in for this message + * @n_buffers: number of #GInputVectors in @buffers, or -1 to indicate @buffers + * is %NULL-terminated + * @from: (allow-none): return location to store the address of the peer who + * transmitted the message, or %NULL + * @length: total number of valid bytes contiguously stored in @buffers + * + * Represents a single message received off the network. For reliable + * connections, this is essentially just an array of buffers (specifically, + * @from can be ignored). for non-reliable connections, it represents a single + * packet as received from the OS. + * + * @n_buffers may be -1 to indicate that @buffers is terminated by a + * #GInputVector with a %NULL buffer pointer. + * + * By providing arrays of #NiceInputMessages to functions like + * nice_agent_recv_messages(), multiple messages may be received with a single + * call, which is more efficient than making multiple calls in a loop. In this + * manner, nice_agent_recv_messages() is analogous to recvmmsg(); and + * #NiceInputMessage to struct mmsghdr. + * + * Since: 0.1.5 + */ +typedef struct { + GInputVector *buffers; + gint n_buffers; /* may be -1 to indicate @buffers is NULL-terminated */ + NiceAddress *from; /* return location for address of message sender */ + gsize length; /* sum of the lengths of @buffers */ +} NiceInputMessage; + +/** + * NiceOutputMessage: + * @buffers: (array length=n_buffers): unowned array of #GOutputVector buffers + * which contain data to transmit for this message + * @n_buffers: number of #GOutputVectors in @buffers, or -1 to indicate @buffers + * is %NULL-terminated + * + * Represents a single message to transmit on the network. For + * reliable connections, this is essentially just an array of + * buffer. for non-reliable connections, it represents a single packet + * to send to the OS. + * + * @n_buffers may be -1 to indicate that @buffers is terminated by a + * #GOutputVector with a %NULL buffer pointer. + * + * By providing arrays of #NiceOutputMessages to functions like + * nice_agent_send_messages_nonblocking(), multiple messages may be transmitted + * with a single call, which is more efficient than making multiple calls in a + * loop. In this manner, nice_agent_send_messages_nonblocking() is analogous to + * sendmmsg(); and #NiceOutputMessage to struct mmsghdr. + * + * Since: 0.1.5 + */ +typedef struct { + GOutputVector *buffers; + gint n_buffers; +} NiceOutputMessage; + + +#define NICE_TYPE_AGENT nice_agent_get_type() + +#define NICE_AGENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + NICE_TYPE_AGENT, NiceAgent)) + +#define NICE_AGENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + NICE_TYPE_AGENT, NiceAgentClass)) + +#define NICE_IS_AGENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + NICE_TYPE_AGENT)) + +#define NICE_IS_AGENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + NICE_TYPE_AGENT)) + +#define NICE_AGENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + NICE_TYPE_AGENT, NiceAgentClass)) + +typedef struct _NiceAgentClass NiceAgentClass; + +struct _NiceAgentClass +{ + GObjectClass parent_class; +}; + + +GType nice_agent_get_type (void); + + +/** + * NICE_AGENT_MAX_REMOTE_CANDIDATES: + * + * A hard limit for the number of remote candidates. This + * limit is enforced to protect against malevolent remote + * clients. + */ +#define NICE_AGENT_MAX_REMOTE_CANDIDATES 25 + +/** + * NiceComponentState: + * @NICE_COMPONENT_STATE_DISCONNECTED: No activity scheduled + * @NICE_COMPONENT_STATE_GATHERING: Gathering local candidates + * @NICE_COMPONENT_STATE_CONNECTING: Establishing connectivity + * @NICE_COMPONENT_STATE_CONNECTED: At least one working candidate pair + * @NICE_COMPONENT_STATE_READY: ICE concluded, candidate pair selection + * is now final + * @NICE_COMPONENT_STATE_FAILED: Connectivity checks have been completed, + * but connectivity was not established + * @NICE_COMPONENT_STATE_LAST: Dummy state + * + * An enum representing the state of a component. + * See also: #NiceAgent::component-state-changed + */ +typedef enum +{ + NICE_COMPONENT_STATE_DISCONNECTED, + NICE_COMPONENT_STATE_GATHERING, + NICE_COMPONENT_STATE_CONNECTING, + NICE_COMPONENT_STATE_CONNECTED, + NICE_COMPONENT_STATE_READY, + NICE_COMPONENT_STATE_FAILED, + NICE_COMPONENT_STATE_LAST +} NiceComponentState; + + +/** + * NiceComponentType: + * @NICE_COMPONENT_TYPE_RTP: RTP Component type + * @NICE_COMPONENT_TYPE_RTCP: RTCP Component type + * + * Convenience enum representing the type of a component for use as the + * component_id for RTP/RTCP usages. + + Example of use. + + nice_agent_send (agent, stream_id, NICE_COMPONENT_TYPE_RTP, len, buf); + + + */ +typedef enum +{ + NICE_COMPONENT_TYPE_RTP = 1, + NICE_COMPONENT_TYPE_RTCP = 2 +} NiceComponentType; + + +/** + * NiceCompatibility: + * @NICE_COMPATIBILITY_RFC5245: Use compatibility with the RFC5245 ICE-UDP specs + * and RFC6544 ICE-TCP specs + * @NICE_COMPATIBILITY_GOOGLE: Use compatibility for Google Talk specs + * @NICE_COMPATIBILITY_MSN: Use compatibility for MSN Messenger specs + * @NICE_COMPATIBILITY_WLM2009: Use compatibility with Windows Live Messenger + * 2009 + * @NICE_COMPATIBILITY_OC2007: Use compatibility with Microsoft Office Communicator 2007 + * @NICE_COMPATIBILITY_OC2007R2: Use compatibility with Microsoft Office Communicator 2007 R2 + * @NICE_COMPATIBILITY_DRAFT19: Use compatibility for ICE Draft 19 specs + * @NICE_COMPATIBILITY_LAST: Dummy last compatibility mode + * + * An enum to specify which compatible specifications the #NiceAgent should use. + * Use with nice_agent_new() + * + * @NICE_COMPATIBILITY_DRAFT19 is deprecated and should not be used + * in newly-written code. It is kept for compatibility reasons and + * represents the same compatibility as @NICE_COMPATIBILITY_RFC5245 + + + If @NICE_COMPATIBILITY_RFC5245 compatibility mode is used for a non-reliable + agent, then ICE-UDP will be used with higher priority and ICE-TCP will also + be used when the UDP connectivity fails. If it is used with a reliable agent, + then ICE-UDP will be used with the TCP-Over-UDP (#PseudoTcpSocket) if ICE-TCP + fails and ICE-UDP succeeds. + + + * + */ +typedef enum +{ + NICE_COMPATIBILITY_RFC5245 = 0, + NICE_COMPATIBILITY_DRAFT19 = NICE_COMPATIBILITY_RFC5245, + NICE_COMPATIBILITY_GOOGLE, + NICE_COMPATIBILITY_MSN, + NICE_COMPATIBILITY_WLM2009, + NICE_COMPATIBILITY_OC2007, + NICE_COMPATIBILITY_OC2007R2, + NICE_COMPATIBILITY_LAST = NICE_COMPATIBILITY_OC2007R2, +} NiceCompatibility; + +/** + * NiceProxyType: + * @NICE_PROXY_TYPE_NONE: Do not use a proxy + * @NICE_PROXY_TYPE_SOCKS5: Use a SOCKS5 proxy + * @NICE_PROXY_TYPE_HTTP: Use an HTTP proxy + * @NICE_PROXY_TYPE_LAST: Dummy last proxy type + * + * An enum to specify which proxy type to use for relaying. + * Note that the proxies will only be used with TCP TURN relaying. + * See also: #NiceAgent:proxy-type + * + * Since: 0.0.4 + */ +typedef enum +{ + NICE_PROXY_TYPE_NONE = 0, + NICE_PROXY_TYPE_SOCKS5, + NICE_PROXY_TYPE_HTTP, + NICE_PROXY_TYPE_LAST = NICE_PROXY_TYPE_HTTP, +} NiceProxyType; + +/** + * NiceNominationMode: + * @NICE_NOMINATION_MODE_AGGRESSIVE: Aggressive nomination mode + * @NICE_NOMINATION_MODE_REGULAR: Regular nomination mode + * + * An enum to specity the kind of nomination mode to use by + * the agent, as described in RFC 5245. Two modes exists, + * regular and aggressive. They differ by the way the controlling + * agent chooses to put the USE-CANDIDATE attribute in its STUN + * messages. The aggressive mode is supposed to nominate a pair + * faster, than the regular mode, potentially causing the nominated + * pair to change until the connection check completes. + * + * Since: 0.1.15 + */ +typedef enum +{ + NICE_NOMINATION_MODE_REGULAR = 0, + NICE_NOMINATION_MODE_AGGRESSIVE, +} NiceNominationMode; + +/** + * NiceAgentOption: + * @NICE_AGENT_OPTION_REGULAR_NOMINATION: Enables regular nomination, default + * is aggrssive mode (see #NiceNominationMode). + * @NICE_AGENT_OPTION_RELIABLE: Enables reliable mode, possibly using PseudoTCP, * see nice_agent_new_reliable(). + * @NICE_AGENT_OPTION_LITE_MODE: Enable lite mode + * @NICE_AGENT_OPTION_ICE_TRICKLE: Enable ICE trickle mode + * @NICE_AGENT_OPTION_SUPPORT_RENOMINATION: Enable renomination triggered by NOMINATION STUN attribute + * proposed here: https://tools.ietf.org/html/draft-thatcher-ice-renomination-00 + * + * These are options that can be passed to nice_agent_new_full(). They set + * various properties on the agent. Not including them sets the property to + * the other value. + * + * Since: 0.1.15 + */ +typedef enum { + NICE_AGENT_OPTION_REGULAR_NOMINATION = 1 << 0, + NICE_AGENT_OPTION_RELIABLE = 1 << 1, + NICE_AGENT_OPTION_LITE_MODE = 1 << 2, + NICE_AGENT_OPTION_ICE_TRICKLE = 1 << 3, + NICE_AGENT_OPTION_SUPPORT_RENOMINATION = 1 << 4, +} NiceAgentOption; + +/** + * NiceAgentRecvFunc: + * @agent: The #NiceAgent Object + * @stream_id: The id of the stream + * @component_id: The id of the component of the stream + * which received the data + * @len: The length of the data + * @buf: The buffer containing the data received + * @user_data: The user data set in nice_agent_attach_recv() + * + * Callback function when data is received on a component + * + */ +typedef void (*NiceAgentRecvFunc) ( + NiceAgent *agent, guint stream_id, guint component_id, guint len, + gchar *buf, gpointer user_data); + + +/** + * nice_agent_new: + * @ctx: The Glib Mainloop Context to use for timers + * @compat: The compatibility mode of the agent + * + * Create a new #NiceAgent. + * The returned object must be freed with g_object_unref() + * + * Returns: The new agent GObject + */ +NiceAgent * +nice_agent_new (GMainContext *ctx, NiceCompatibility compat); + + +/** + * nice_agent_new_reliable: + * @ctx: The Glib Mainloop Context to use for timers + * @compat: The compatibility mode of the agent + * + * Create a new #NiceAgent in reliable mode. If the connectivity is established + * through ICE-UDP, then a #PseudoTcpSocket will be transparently used to + * ensure reliability of the messages. + * The returned object must be freed with g_object_unref() + * See also: #NiceAgent::reliable-transport-writable + * + * Since: 0.0.11 + * + * Returns: The new agent GObject + */ +NiceAgent * +nice_agent_new_reliable (GMainContext *ctx, NiceCompatibility compat); + +/** + * nice_agent_new_full: + * @ctx: The Glib Mainloop Context to use for timers + * @compat: The compatibility mode of the agent + * @flags: Flags to set the properties + * + * Create a new #NiceAgent with parameters that must be be defined at + * construction time. + * The returned object must be freed with g_object_unref() + * See also: #NiceNominationMode and #NiceAgentOption + * + * Since: 0.1.15 + * + * Returns: The new agent GObject + */ +NiceAgent * +nice_agent_new_full (GMainContext *ctx, + NiceCompatibility compat, + NiceAgentOption flags); + +/** + * nice_agent_add_local_address: + * @agent: The #NiceAgent Object + * @addr: The address to listen to + * If the port is 0, then a random port will be chosen by the system + * + * Add a local address from which to derive local host candidates for + * candidate gathering. + * + * Since 0.0.5, if this method is not called, libnice will automatically + * discover the local addresses available + * + * + * See also: nice_agent_gather_candidates() + * Returns: %TRUE on success, %FALSE on fatal (memory allocation) errors + */ +gboolean +nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr); + +/** + * nice_agent_add_stream: + * @agent: The #NiceAgent Object + * @n_components: The number of components to add to the stream + * + * Adds a data stream to @agent containing @n_components components. The + * returned stream ID is guaranteed to be positive on success. + * + * Returns: The ID of the new stream, 0 on failure + **/ +guint +nice_agent_add_stream ( + NiceAgent *agent, + guint n_components); + +/** + * nice_agent_remove_stream: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream to remove + * + * Remove and free a previously created data stream from @agent. If any I/O + * streams have been created using nice_agent_get_io_stream(), they should be + * closed completely using g_io_stream_close() before this is called, or they + * will get broken pipe errors. + * + **/ +void +nice_agent_remove_stream ( + NiceAgent *agent, + guint stream_id); + + +/** + * nice_agent_set_port_range: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @min_port: The minimum port to use + * @max_port: The maximum port to use + * + * Sets a preferred port range for allocating host candidates. + * + * If a local host candidate cannot be created on that port + * range, then the nice_agent_gather_candidates() call will fail. + * + * + * This MUST be called before nice_agent_gather_candidates() + * + * + */ +void +nice_agent_set_port_range ( + NiceAgent *agent, + guint stream_id, + guint component_id, + guint min_port, + guint max_port); + +/** + * nice_agent_set_relay_info: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @server_ip: The IP address of the TURN server + * @server_port: The port of the TURN server + * @username: The TURN username to use for the allocate + * @password: The TURN password to use for the allocate + * @type: The type of relay to use + * + * Sets the settings for using a relay server during the candidate discovery. + * This may be called multiple times to add multiple relay servers to the + * discovery process; one TCP and one UDP, for example. + * + * Returns: %TRUE if the TURN settings were accepted. + * %FALSE if the address was invalid. + */ +gboolean nice_agent_set_relay_info( + NiceAgent *agent, + guint stream_id, + guint component_id, + const gchar *server_ip, + guint server_port, + const gchar *username, + const gchar *password, + NiceRelayType type); + +/** + * nice_agent_gather_candidates: + * @agent: The #NiceAgent object + * @stream_id: The ID of the stream to start + * + * Allocate and start listening on local candidate ports and start the remote + * candidate gathering process. + * Once done, #NiceAgent::candidate-gathering-done is called for the stream. + * As soon as this function is called, #NiceAgent::new-candidate signals may be + * emitted, even before this function returns. + * + * nice_agent_get_local_candidates() will only return non-empty results after + * calling this function. + * + * See also: nice_agent_add_local_address() + * See also: nice_agent_set_port_range() + * + * Returns: %FALSE if the stream ID is invalid or if a host candidate couldn't + * be allocated on the requested interfaces/ports; %TRUE otherwise + * + + + Local addresses can be previously set with nice_agent_add_local_address() + + + Since 0.0.5, If no local address was previously added, then the nice agent + will automatically detect the local address using + nice_interfaces_get_local_ips() + + + */ +gboolean +nice_agent_gather_candidates ( + NiceAgent *agent, + guint stream_id); + +/** + * nice_agent_set_remote_credentials: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @ufrag: nul-terminated string containing an ICE username fragment + * (length must be between 22 and 256 chars) + * @pwd: nul-terminated string containing an ICE password + * (length must be between 4 and 256 chars) + * + * Sets the remote credentials for stream @stream_id. + * + + + Stream credentials do not override per-candidate credentials if set + + + Due to the native of peer-reflexive candidates, any agent using a per-stream + credentials (RFC5245, WLM2009, OC2007R2 and DRAFT19) instead of + per-candidate credentials (GOOGLE, MSN, OC2007), must + use the nice_agent_set_remote_credentials() API instead of setting the + username and password on the candidates. + + + * + * Returns: %TRUE on success, %FALSE on error. + */ +gboolean +nice_agent_set_remote_credentials ( + NiceAgent *agent, + guint stream_id, + const gchar *ufrag, const gchar *pwd); + + +/** + * nice_agent_set_local_credentials: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @ufrag: nul-terminated string containing an ICE username fragment + * (length must be between 22 and 256 chars) + * @pwd: nul-terminated string containing an ICE password + * (length must be between 4 and 256 chars) + * + * Sets the local credentials for stream @stream_id. + * + + + This is only effective before ICE negotiation has started. + + + * + * Since 0.1.11 + * Returns: %TRUE on success, %FALSE on error. + */ +gboolean +nice_agent_set_local_credentials ( + NiceAgent *agent, + guint stream_id, + const gchar *ufrag, + const gchar *pwd); + + +/** + * nice_agent_get_local_credentials: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @ufrag: (out callee-allocates): return location for a nul-terminated string + * containing an ICE username fragment; must be freed with g_free() + * @pwd: (out callee-allocates): return location for a nul-terminated string + * containing an ICE password; must be freed with g_free() + * + * Gets the local credentials for stream @stream_id. This may be called any time + * after creating a stream using nice_agent_add_stream(). + * + * An error will be returned if this is called for a non-existent stream, or if + * either of @ufrag or @pwd are %NULL. + * + * Returns: %TRUE on success, %FALSE on error. + */ +gboolean +nice_agent_get_local_credentials ( + NiceAgent *agent, + guint stream_id, + gchar **ufrag, gchar **pwd); + +/** + * nice_agent_set_remote_candidates: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream the candidates are for + * @component_id: The ID of the component the candidates are for + * @candidates: (element-type NiceCandidate) (transfer none): a #GSList of + * #NiceCandidate items describing each candidate to add + * + * Sets, adds or updates the remote candidates for a component of a stream. + * + + + NICE_AGENT_MAX_REMOTE_CANDIDATES is the absolute maximum limit + for remote candidates. + + + You must first call nice_agent_gather_candidates() and wait for the + #NiceAgent::candidate-gathering-done signale before + calling nice_agent_set_remote_candidates() + + + Since 0.1.3, there is no need to wait for the candidate-gathering-done signal. + Remote candidates can be set even while gathering local candidates. + Newly discovered local candidates will automatically be paired with + existing remote candidates. + + + * + * Returns: The number of candidates added, negative on errors (memory + * allocation error or invalid component) + **/ +int +nice_agent_set_remote_candidates ( + NiceAgent *agent, + guint stream_id, + guint component_id, + const GSList *candidates); + + +/** + * nice_agent_send: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream to send to + * @component_id: The ID of the component to send to + * @len: The length of the buffer to send + * @buf: The buffer of data to send + * + * Sends a data payload over a stream's component. + * + + + Component state MUST be NICE_COMPONENT_STATE_READY, or as a special case, + in any state if component was in READY state before and was then restarted + + + In reliable mode, the -1 error value means either that you are not yet + connected or that the send buffer is full (equivalent to EWOULDBLOCK). + In both cases, you simply need to wait for the + #NiceAgent::reliable-transport-writable signal to be fired before resending + the data. + + + In non-reliable mode, it will virtually never happen with UDP sockets, but + it might happen if the active candidate is a TURN-TCP connection that got + disconnected. + + + In both reliable and non-reliable mode, a -1 error code could also mean that + the stream_id and/or component_id are invalid. + + + * + * Returns: The number of bytes sent, or negative error code + */ +gint +nice_agent_send ( + NiceAgent *agent, + guint stream_id, + guint component_id, + guint len, + const gchar *buf); + +/** + * nice_agent_send_messages_nonblocking: + * @agent: a #NiceAgent + * @stream_id: the ID of the stream to send to + * @component_id: the ID of the component to send to + * @messages: (array length=n_messages): array of messages to send, of at least + * @n_messages entries in length + * @n_messages: number of entries in @messages + * @cancellable: (allow-none): a #GCancellable to cancel the operation from + * another thread, or %NULL + * @error: (allow-none): return location for a #GError, or %NULL + * + * Sends multiple messages on the socket identified by the given + * stream/component pair. Transmission is non-blocking, so a + * %G_IO_ERROR_WOULD_BLOCK error may be returned if the send buffer is full. + * + * As with nice_agent_send(), the given component must be in + * %NICE_COMPONENT_STATE_READY or, as a special case, in any state if it was + * previously ready and was then restarted. + * + * On success, the number of messages written to the socket will be returned, + * which may be less than @n_messages if transmission would have blocked + * part-way through. Zero will be returned if @n_messages is zero, or if + * transmission would have blocked on the first message. + * + * In reliable mode, it is instead recommended to use + * nice_agent_send(). The return value can be less than @n_messages + * or 0 even if it is still possible to send a partial message. In + * this case, "nice-agent-writable" will never be triggered, so the + * application would have to use nice_agent_sent() to fill the buffer or have + * to retry sending at a later point. + * + * On failure, -1 will be returned and @error will be set. If the #NiceAgent is + * reliable and the socket is not yet connected, %G_IO_ERROR_BROKEN_PIPE will be + * returned; if the write buffer is full, %G_IO_ERROR_WOULD_BLOCK will be + * returned. In both cases, wait for the #NiceAgent::reliable-transport-writable + * signal before trying again. If the given @stream_id or @component_id are + * invalid or not yet connected, %G_IO_ERROR_BROKEN_PIPE will be returned. + * %G_IO_ERROR_FAILED will be returned for other errors. + * + * Returns: the number of messages sent (may be zero), or -1 on error + * + * Since: 0.1.5 + */ +gint +nice_agent_send_messages_nonblocking ( + NiceAgent *agent, + guint stream_id, + guint component_id, + const NiceOutputMessage *messages, + guint n_messages, + GCancellable *cancellable, + GError **error); + +/** + * nice_agent_get_local_candidates: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * + * Retrieve from the agent the list of all local candidates + * for a stream's component + * + + + The caller owns the returned GSList as well as the candidates contained + within it. + To get full results, the client should wait for the + #NiceAgent::candidate-gathering-done signal. + + + * + * Returns: (element-type NiceCandidate) (transfer full): a #GSList of + * #NiceCandidate objects representing the local candidates of @agent + **/ +GSList * +nice_agent_get_local_candidates ( + NiceAgent *agent, + guint stream_id, + guint component_id); + + +/** + * nice_agent_get_remote_candidates: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * + * Get a list of the remote candidates set on a stream's component + * + + + The caller owns the returned GSList as well as the candidates contained + within it. + + + The list of remote candidates can change during processing. + The client should register for the #NiceAgent::new-remote-candidate signal + to get notified of new remote candidates. + + + * + * Returns: (element-type NiceCandidate) (transfer full): a #GSList of + * #NiceCandidates objects representing the remote candidates set on the @agent + **/ +GSList * +nice_agent_get_remote_candidates ( + NiceAgent *agent, + guint stream_id, + guint component_id); + +/** + * nice_agent_restart: + * @agent: The #NiceAgent Object + * + * Restarts the session as defined in ICE draft 19. This function + * needs to be called both when initiating (ICE spec section 9.1.1.1. + * "ICE Restarts"), as well as when reacting (spec section 9.2.1.1. + * "Detecting ICE Restart") to a restart. + * + * Returns: %TRUE on success %FALSE on error + **/ +gboolean +nice_agent_restart ( + NiceAgent *agent); + +/** + * nice_agent_restart_stream: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * + * Restarts a single stream as defined in RFC 5245. This function + * needs to be called both when initiating (ICE spec section 9.1.1.1. + * "ICE Restarts"), as well as when reacting (spec section 9.2.1.1. + * "Detecting ICE Restart") to a restart. + * + * Unlike nice_agent_restart(), this applies to a single stream. It also + * does not generate a new tie breaker. + * + * Returns: %TRUE on success %FALSE on error + * + * Since: 0.1.6 + **/ +gboolean +nice_agent_restart_stream ( + NiceAgent *agent, + guint stream_id); + + +/** + * nice_agent_attach_recv: (skip) + * @agent: The #NiceAgent Object + * @stream_id: The ID of stream + * @component_id: The ID of the component + * @ctx: The Glib Mainloop Context to use for listening on the component + * @func: The callback function to be called when data is received on + * the stream's component (will not be called for STUN messages that + * should be handled by #NiceAgent itself) + * @data: user data associated with the callback + * + * Attaches the stream's component's sockets to the Glib Mainloop Context in + * order to be notified whenever data becomes available for a component, + * and to enable #NiceAgent to receive STUN messages (during the + * establishment of ICE connectivity). + * + * This must not be used in combination with nice_agent_recv_messages() (or + * #NiceIOStream or #NiceInputStream) on the same stream/component pair. + * + * Calling nice_agent_attach_recv() with a %NULL @func will detach any existing + * callback and cause reception to be paused for the given stream/component + * pair. You must iterate the previously specified #GMainContext sufficiently to + * ensure all pending I/O callbacks have been received before calling this + * function to unset @func, otherwise data loss of received packets may occur. + * + * Returns: %TRUE on success, %FALSE if the stream or component IDs are invalid. + */ +gboolean +nice_agent_attach_recv ( + NiceAgent *agent, + guint stream_id, + guint component_id, + GMainContext *ctx, + NiceAgentRecvFunc func, + gpointer data); + +/** + * nice_agent_recv: + * @agent: a #NiceAgent + * @stream_id: the ID of the stream to receive on + * @component_id: the ID of the component to receive on + * @buf: (array length=buf_len) (out caller-allocates): caller-allocated buffer + * to write the received data into, of length at least @buf_len + * @buf_len: length of @buf + * @cancellable: (allow-none): a #GCancellable to allow the operation to be + * cancelled from another thread, or %NULL + * @error: (allow-none): return location for a #GError, or %NULL + * + * A single-message version of nice_agent_recv_messages(). + * + * Returns: the number of bytes written to @buf on success (guaranteed to be + * greater than 0 unless @buf_len is 0), 0 if in reliable mode and the remote + * peer closed the stream, or -1 on error + * + * Since: 0.1.5 + */ +gssize +nice_agent_recv ( + NiceAgent *agent, + guint stream_id, + guint component_id, + guint8 *buf, + gsize buf_len, + GCancellable *cancellable, + GError **error); + +/** + * nice_agent_recv_messages: + * @agent: a #NiceAgent + * @stream_id: the ID of the stream to receive on + * @component_id: the ID of the component to receive on + * @messages: (array length=n_messages) (out caller-allocates): caller-allocated + * array of #NiceInputMessages to write the received messages into, of length at + * least @n_messages + * @n_messages: number of entries in @messages + * @cancellable: (allow-none): a #GCancellable to allow the operation to be + * cancelled from another thread, or %NULL + * @error: (allow-none): return location for a #GError, or %NULL + * + * Block on receiving data from the given stream/component combination on + * @agent, returning only once exactly @n_messages messages have been received + * and written into @messages, the stream is closed by the other end or by + * calling nice_agent_remove_stream(), or @cancellable is cancelled. + * + * Any STUN packets received will not be added to @messages; instead, + * they'll be passed for processing to #NiceAgent itself. Since #NiceAgent + * does not poll for messages on its own, it's therefore essential to keep + * calling this function for ICE connection establishment to work. + * + * In the non-error case, in reliable mode, this will block until all buffers in + * all @n_messages have been filled with received data (i.e. @messages is + * treated as a large, flat array of buffers). In non-reliable mode, it will + * block until @n_messages messages have been received, each of which does not + * have to fill all the buffers in its #NiceInputMessage. In the non-reliable + * case, each #NiceInputMessage must have enough buffers to contain an entire + * message (65536 bytes), or any excess data may be silently dropped. + * + * For each received message, #NiceInputMessage::length will be set to the + * number of valid bytes stored in the message’s buffers. The bytes are stored + * sequentially in the buffers; there are no gaps apart from at the end of the + * buffer array (in non-reliable mode). If non-%NULL on input, + * #NiceInputMessage::from will have the address of the sending peer stored in + * it. The base addresses, sizes, and number of buffers in each message will not + * be modified in any case. + * + * This must not be used in combination with nice_agent_attach_recv() on the + * same stream/component pair. + * + * If the stream/component pair doesn’t exist, or if a suitable candidate socket + * hasn’t yet been selected for it, a %G_IO_ERROR_BROKEN_PIPE error will be + * returned. A %G_IO_ERROR_CANCELLED error will be returned if the operation was + * cancelled. %G_IO_ERROR_FAILED will be returned for other errors. + * + * Returns: the number of valid messages written to @messages on success + * (guaranteed to be greater than 0 unless @n_messages is 0), 0 if the remote + * peer closed the stream, or -1 on error + * + * Since: 0.1.5 + */ +gint +nice_agent_recv_messages ( + NiceAgent *agent, + guint stream_id, + guint component_id, + NiceInputMessage *messages, + guint n_messages, + GCancellable *cancellable, + GError **error); + +/** + * nice_agent_recv_nonblocking: + * @agent: a #NiceAgent + * @stream_id: the ID of the stream to receive on + * @component_id: the ID of the component to receive on + * @buf: (array length=buf_len) (out caller-allocates): caller-allocated buffer + * to write the received data into, of length at least @buf_len + * @buf_len: length of @buf + * @cancellable: (allow-none): a #GCancellable to allow the operation to be + * cancelled from another thread, or %NULL + * @error: (allow-none): return location for a #GError, or %NULL + * + * A single-message version of nice_agent_recv_messages_nonblocking(). + * + * Returns: the number of bytes received into @buf on success (guaranteed to be + * greater than 0 unless @buf_len is 0), 0 if in reliable mode and the remote + * peer closed the stream, or -1 on error + * + * Since: 0.1.5 + */ +gssize +nice_agent_recv_nonblocking ( + NiceAgent *agent, + guint stream_id, + guint component_id, + guint8 *buf, + gsize buf_len, + GCancellable *cancellable, + GError **error); + +/** + * nice_agent_recv_messages_nonblocking: + * @agent: a #NiceAgent + * @stream_id: the ID of the stream to receive on + * @component_id: the ID of the component to receive on + * @messages: (array length=n_messages) (out caller-allocates): caller-allocated + * array of #NiceInputMessages to write the received messages into, of length at + * least @n_messages + * @n_messages: number of entries in @messages + * @cancellable: (allow-none): a #GCancellable to allow the operation to be + * cancelled from another thread, or %NULL + * @error: (allow-none): return location for a #GError, or %NULL + * + * Try to receive data from the given stream/component combination on @agent, + * without blocking. If receiving data would block, -1 is returned and + * %G_IO_ERROR_WOULD_BLOCK is set in @error. If any other error occurs, -1 is + * returned and @error is set accordingly. Otherwise, 0 is returned if (and only + * if) @n_messages is 0. In all other cases, the number of valid messages stored + * in @messages is returned, and will be greater than 0. + * + * This function behaves similarly to nice_agent_recv_messages(), except that it + * will not block on filling (in reliable mode) or receiving (in non-reliable + * mode) exactly @n_messages messages. In reliable mode, it will receive bytes + * into @messages until it would block; in non-reliable mode, it will receive + * messages until it would block. + * + * Any STUN packets received will not be added to @messages; instead, + * they'll be passed for processing to #NiceAgent itself. Since #NiceAgent + * does not poll for messages on its own, it's therefore essential to keep + * calling this function for ICE connection establishment to work. + * + * As this function is non-blocking, @cancellable is included only for parity + * with nice_agent_recv_messages(). If @cancellable is cancelled before this + * function is called, a %G_IO_ERROR_CANCELLED error will be returned + * immediately. + * + * This must not be used in combination with nice_agent_attach_recv() on the + * same stream/component pair. + * + * Returns: the number of valid messages written to @messages on success + * (guaranteed to be greater than 0 unless @n_messages is 0), 0 if in reliable + * mode and the remote peer closed the stream, or -1 on error + * + * Since: 0.1.5 + */ +gint +nice_agent_recv_messages_nonblocking ( + NiceAgent *agent, + guint stream_id, + guint component_id, + NiceInputMessage *messages, + guint n_messages, + GCancellable *cancellable, + GError **error); + +/** + * nice_agent_set_selected_pair: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @lfoundation: The local foundation of the candidate to use + * @rfoundation: The remote foundation of the candidate to use + * + * Sets the selected candidate pair for media transmission + * for a given stream's component. Calling this function will + * disable all further ICE processing (connection check, + * state machine updates, etc). Note that keepalives will + * continue to be sent. + * + * Returns: %TRUE on success, %FALSE if the candidate pair cannot be found + */ +gboolean +nice_agent_set_selected_pair ( + NiceAgent *agent, + guint stream_id, + guint component_id, + const gchar *lfoundation, + const gchar *rfoundation); + +/** + * nice_agent_get_selected_pair: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @local: The local selected candidate + * @remote: The remote selected candidate + * + * Retreive the selected candidate pair for media transmission + * for a given stream's component. + * + * Returns: %TRUE on success, %FALSE if there is no selected candidate pair + */ +gboolean +nice_agent_get_selected_pair ( + NiceAgent *agent, + guint stream_id, + guint component_id, + NiceCandidate **local, + NiceCandidate **remote); + +/** + * nice_agent_get_selected_socket: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * + * Retreive the local socket associated with the selected candidate pair + * for media transmission for a given stream's component. + * + * This is useful for adding ICE support to legacy applications that already + * have a protocol that maintains a connection. If the socket is duplicated + * before unrefing the agent, the application can take over and continue to use + * it. New applications are encouraged to use the built in libnice stream + * handling instead and let libnice handle the connection maintenance. + * + * Users of this method are encouraged to not use a TURN relay or any kind + * of proxy, as in this case, the socket will not be available to the + * application because the packets are encapsulated. + * + * Returns: (transfer full) (nullable): pointer to the #GSocket, or %NULL if + * there is no selected candidate or if the selected candidate is a relayed + * candidate. + * + * Since: 0.1.5 + */ +GSocket * +nice_agent_get_selected_socket ( + NiceAgent *agent, + guint stream_id, + guint component_id); + +/** + * nice_agent_set_selected_remote_candidate: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @candidate: The #NiceCandidate to select + * + * Sets the selected remote candidate for media transmission + * for a given stream's component. This is used to force the selection of + * a specific remote candidate even when connectivity checks are failing + * (e.g. non-ICE compatible candidates). + * Calling this function will disable all further ICE processing + * (connection check, state machine updates, etc). Note that keepalives will + * continue to be sent. + * + * Returns: %TRUE on success, %FALSE on failure + */ +gboolean +nice_agent_set_selected_remote_candidate ( + NiceAgent *agent, + guint stream_id, + guint component_id, + NiceCandidate *candidate); + + +/** + * nice_agent_set_stream_tos: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @tos: The ToS to set + * + * Sets the IP_TOS and/or IPV6_TCLASS field on the stream's sockets' options + * + * Since: 0.0.9 + */ +void nice_agent_set_stream_tos ( + NiceAgent *agent, + guint stream_id, + gint tos); + + + +/** + * nice_agent_set_software: + * @agent: The #NiceAgent Object + * @software: The value of the SOFTWARE attribute to add. + * + * This function will set the value of the SOFTWARE attribute to be added to + * STUN requests, responses and error responses sent during connectivity checks. + * + * The SOFTWARE attribute will only be added in the #NICE_COMPATIBILITY_RFC5245 + * and #NICE_COMPATIBILITY_WLM2009 compatibility modes. + * + * + * + + The @software argument will be appended with the libnice version before + being sent. + + + The @software argument must be in UTF-8 encoding and only the first + 128 characters will be sent. + + + * + * Since: 0.0.10 + * + */ +void nice_agent_set_software ( + NiceAgent *agent, + const gchar *software); + +/** + * nice_agent_set_stream_name: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream to change + * @name: The new name of the stream or %NULL + * + * This function will assign a media type to a stream. The only values + * that can be used to produce a valid SDP are: "audio", "video", + * "text", "application", "image" and "message". + * + * This is only useful when parsing and generating an SDP of the + * candidates. + * + * See also: nice_agent_generate_local_sdp() + * See also: nice_agent_parse_remote_sdp() + * See also: nice_agent_get_stream_name() + * + * Returns: %TRUE if the name has been set. %FALSE in case of error + * (invalid stream or duplicate name). + * Since: 0.1.4 + */ +gboolean nice_agent_set_stream_name ( + NiceAgent *agent, + guint stream_id, + const gchar *name); + +/** + * nice_agent_get_stream_name: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream to change + * + * This function will return the name assigned to a stream. + + * See also: nice_agent_set_stream_name() + * + * Returns: The name of the stream. The name is only valid while the stream + * exists or until it changes through a call to nice_agent_set_stream_name(). + * + * + * Since: 0.1.4 + */ +const gchar *nice_agent_get_stream_name ( + NiceAgent *agent, + guint stream_id); + +/** + * nice_agent_get_default_local_candidate: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * + * This helper function will return the recommended default candidate to be + * used for non-ICE compatible clients. This will usually be the candidate + * with the lowest priority, since it will be the longest path but the one with + * the most chances of success. + * + + This function is only useful in order to manually generate the + local SDP + + * + * + * Returns: The candidate to be used as the default candidate, or %NULL in case + * of error. Must be freed with nice_candidate_free() once done. + * + */ +NiceCandidate * +nice_agent_get_default_local_candidate ( + NiceAgent *agent, + guint stream_id, + guint component_id); + +/** + * nice_agent_generate_local_sdp: + * @agent: The #NiceAgent Object + * + * Generate an SDP string containing the local candidates and credentials for + * all streams and components in the agent. + * + + + The SDP will not contain any codec lines and the 'm' line will not list + any payload types. + + + It is highly recommended to set names on the streams prior to calling this + function. Unnamed streams will show up as '-' in the 'm' line, but the SDP + will not be parseable with nice_agent_parse_remote_sdp() if a stream is + unnamed. + + + The default candidate in the SDP will be selected based on the lowest + priority candidate for the first component. + + + * + * See also: nice_agent_set_stream_name() + * See also: nice_agent_parse_remote_sdp() + * See also: nice_agent_generate_local_stream_sdp() + * See also: nice_agent_generate_local_candidate_sdp() + * See also: nice_agent_get_default_local_candidate() + * + * Returns: A string representing the local SDP. Must be freed with g_free() + * once done. + * + * Since: 0.1.4 + **/ +gchar * +nice_agent_generate_local_sdp ( + NiceAgent *agent); + +/** + * nice_agent_generate_local_stream_sdp: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @include_non_ice: Whether or not to include non ICE specific lines + * (m=, c= and a=rtcp: lines) + * + * Generate an SDP string containing the local candidates and credentials + * for a stream. + * + + + The SDP will not contain any codec lines and the 'm' line will not list + any payload types. + + + It is highly recommended to set the name of the stream prior to calling this + function. Unnamed streams will show up as '-' in the 'm' line. + + + The default candidate in the SDP will be selected based on the lowest + priority candidate. + + + * + * See also: nice_agent_set_stream_name() + * See also: nice_agent_parse_remote_stream_sdp() + * See also: nice_agent_generate_local_sdp() + * See also: nice_agent_generate_local_candidate_sdp() + * See also: nice_agent_get_default_local_candidate() + * + * Returns: A string representing the local SDP for the stream. Must be freed + * with g_free() once done. + * + * Since: 0.1.4 + **/ +gchar * +nice_agent_generate_local_stream_sdp ( + NiceAgent *agent, + guint stream_id, + gboolean include_non_ice); + +/** + * nice_agent_generate_local_candidate_sdp: + * @agent: The #NiceAgent Object + * @candidate: The candidate to generate + * + * Generate an SDP string representing a local candidate. + * + * See also: nice_agent_parse_remote_candidate_sdp() + * See also: nice_agent_generate_local_sdp() + * See also: nice_agent_generate_local_stream_sdp() + * + * Returns: A string representing the SDP for the candidate. Must be freed + * with g_free() once done. + * + * Since: 0.1.4 + **/ +gchar * +nice_agent_generate_local_candidate_sdp ( + NiceAgent *agent, + NiceCandidate *candidate); + +/** + * nice_agent_parse_remote_sdp: + * @agent: The #NiceAgent Object + * @sdp: The remote SDP to parse + * + * Parse an SDP string and extracts candidates and credentials from it and sets + * them on the agent. + * + * See also: nice_agent_set_stream_name() + * See also: nice_agent_generate_local_sdp() + * See also: nice_agent_parse_remote_stream_sdp() + * See also: nice_agent_parse_remote_candidate_sdp() + * + * Returns: The number of candidates added, negative on errors + * + * Since: 0.1.4 + **/ +int +nice_agent_parse_remote_sdp ( + NiceAgent *agent, + const gchar *sdp); + + +/** + * nice_agent_parse_remote_stream_sdp: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream to parse + * @sdp: The remote SDP to parse + * @ufrag: Pointer to store the ice ufrag if non %NULL. Must be freed with + * g_free() after use + * @pwd: Pointer to store the ice password if non %NULL. Must be freed with + * g_free() after use + * + * Parse an SDP string representing a single stream and extracts candidates + * and credentials from it. + * + * See also: nice_agent_generate_local_stream_sdp() + * See also: nice_agent_parse_remote_sdp() + * See also: nice_agent_parse_remote_candidate_sdp() + * + * Returns: (element-type NiceCandidate) (transfer full): A #GSList of + * candidates parsed from the SDP, or %NULL in case of errors + * + * Since: 0.1.4 + **/ +GSList * +nice_agent_parse_remote_stream_sdp ( + NiceAgent *agent, + guint stream_id, + const gchar *sdp, + gchar **ufrag, + gchar **pwd); + + +/** + * nice_agent_parse_remote_candidate_sdp: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream the candidate belongs to + * @sdp: The remote SDP to parse + * + * Parse an SDP string and extracts the candidate from it. + * + * See also: nice_agent_generate_local_candidate_sdp() + * See also: nice_agent_parse_remote_sdp() + * See also: nice_agent_parse_remote_stream_sdp() + * + * Returns: The parsed candidate or %NULL if there was an error. + * + * Since: 0.1.4 + **/ +NiceCandidate * +nice_agent_parse_remote_candidate_sdp ( + NiceAgent *agent, + guint stream_id, + const gchar *sdp); + +/** + * nice_agent_get_io_stream: + * @agent: A #NiceAgent + * @stream_id: The ID of the stream to wrap + * @component_id: The ID of the component to wrap + * + * Gets a #GIOStream wrapper around the given stream and component in + * @agent. The I/O stream will be valid for as long as @stream_id is valid. + * The #GInputStream and #GOutputStream implement #GPollableInputStream and + * #GPollableOutputStream. + * + * This function may only be called on reliable #NiceAgents. It is a + * programming error to try and create an I/O stream wrapper for an + * unreliable stream. + * + * Returns: (transfer full): A #GIOStream. + * + * Since: 0.1.5 + */ +GIOStream * +nice_agent_get_io_stream ( + NiceAgent *agent, + guint stream_id, + guint component_id); + +/** + * nice_component_state_to_string: + * @state: a #NiceComponentState + * + * Returns a string representation of the state, generally to use in debug + * messages. + * + * Returns: (transfer none): a string representation of @state + * Since: 0.1.6 + */ +const gchar * +nice_component_state_to_string (NiceComponentState state); + +/** + * nice_agent_forget_relays: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * + * Forget all the relay servers previously added using + * nice_agent_set_relay_info(). Currently connected streams will keep + * using the relay as long as they have not been restarted and haven't + * succesfully negotiated a different path. + * + * Returns: %FALSE if the component could not be found, %TRUE otherwise + * + * Since: 0.1.6 + */ +gboolean +nice_agent_forget_relays (NiceAgent *agent, + guint stream_id, + guint component_id); + +/** + * nice_agent_get_component_state: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * + * Retrieves the current state of a component. + * + * Returns: the #NiceComponentState of the component and + * %NICE_COMPONENT_STATE_FAILED if the component was invalid. + * + * Since: 0.1.8 + */ +NiceComponentState +nice_agent_get_component_state (NiceAgent *agent, + guint stream_id, + guint component_id); + +/** + * nice_agent_peer_candidate_gathering_done: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * + * Notifies the agent that the remote peer has concluded candidate gathering and + * thus no more remote candidates are expected to arrive for @stream_id. + * + * This will allow the stream components without a successful connectivity check + * to stop waiting for more candidates to come and finally transit into + * %NICE_COMPONENT_STATE_FAILED. + * + * Calling the function has an effect only when #NiceAgent:trickle-ice is %TRUE. + * + * Returns: %FALSE if the stream could not be found, %TRUE otherwise + * + * Since: 0.1.16 + */ +gboolean +nice_agent_peer_candidate_gathering_done ( + NiceAgent *agent, + guint stream_id); + +/** + * nice_agent_close_async: + * @agent: The #NiceAgent object + * @callback: (nullable): A callback that will be called when the closing is + * complete + * @callback_data: (nullable): A pointer that will be passed to the callback + * + * Asynchronously closes resources the agent has allocated on remote servers. + * + * The agent will call the callback in the current #GMainContext in + * which this function is called. The #GAsyncResult in the callback + * can be ignored as this operation never fails. + * + * Calling this function before freeing the agent makes sure the allocated relay + * ports aren't left behind on TURN server but properly removed. + * + * Since: 0.1.16 + */ +void +nice_agent_close_async (NiceAgent *agent, GAsyncReadyCallback callback, + gpointer callback_data); + +/** + * nice_agent_get_sockets: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * + * Each component can have multiple sockets, this is an API to retrieve them all + * to be able to set properties. Most of the sockets for a component are created when + * calling nice_agent_gather_candidates(), so this API should be called right after to + * able to set properties on the sockets before they are used. + * + * These sockets can be a mix of UDP & TCP sockets depending on the compatibility mode + * and options that have been set. + * + * Returns: (element-type GSocket) (transfer full): An array + * containing all of the sockets for this component. Free with + * g_ptr_array_unref() when done. + * + * Since: 0.1.17 + */ +GPtrArray * +nice_agent_get_sockets (NiceAgent *agent, guint stream_id, guint component_id); + +G_END_DECLS + +#endif /* __LIBNICE_AGENT_H__ */ diff --git a/linux_x86/include/nice/candidate.h b/linux_x86/include/nice/candidate.h new file mode 100644 index 0000000..315daba --- /dev/null +++ b/linux_x86/include/nice/candidate.h @@ -0,0 +1,269 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2006-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2006-2009 Nokia Corporation. All rights reserved. + * Contact: Kai Vehmanen + * + * 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: + * Dafydd Harries, Collabora Ltd. + * Youness Alaoui, Collabora Ltd. + * Kai Vehmanen, Nokia + * + * 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 __LIBNICE_CANDIDATE_H__ +#define __LIBNICE_CANDIDATE_H__ + +#include +#include + + +/** + * SECTION:candidate + * @short_description: ICE candidate representation + * @see_also: #NiceAddress + * @stability: Stable + * + * A representation of an ICE candidate. Make sure you read the ICE drafts[1] to + * understand correctly the concept of ICE candidates. + * + * [1] http://tools.ietf.org/wg/mmusic/draft-ietf-mmusic-ice/ + */ + + +G_BEGIN_DECLS + +/* Constants for determining candidate priorities */ +#define NICE_CANDIDATE_TYPE_PREF_HOST 120 +#define NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE 110 +#define NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED 105 +#define NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE 100 +#define NICE_CANDIDATE_TYPE_PREF_RELAYED_UDP 30 +#define NICE_CANDIDATE_TYPE_PREF_RELAYED 20 + +/* Priority preference constants for MS-ICE compatibility */ +#define NICE_CANDIDATE_TRANSPORT_MS_PREF_UDP 15 +#define NICE_CANDIDATE_TRANSPORT_MS_PREF_TCP 6 +#define NICE_CANDIDATE_DIRECTION_MS_PREF_PASSIVE 2 +#define NICE_CANDIDATE_DIRECTION_MS_PREF_ACTIVE 5 + +/* Max foundation size '1*32ice-char' plus terminating NULL, ICE ID-19 */ +/** + * NICE_CANDIDATE_MAX_FOUNDATION: + * + * The maximum size a candidate foundation can have. + */ +#define NICE_CANDIDATE_MAX_FOUNDATION (32+1) + + +/** + * NiceCandidateType: + * @NICE_CANDIDATE_TYPE_HOST: A host candidate + * @NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: A server reflexive candidate + * @NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: A peer reflexive candidate + * @NICE_CANDIDATE_TYPE_RELAYED: A relay candidate + * + * An enum represneting the type of a candidate + */ +typedef enum +{ + NICE_CANDIDATE_TYPE_HOST, + NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE, + NICE_CANDIDATE_TYPE_PEER_REFLEXIVE, + NICE_CANDIDATE_TYPE_RELAYED, +} NiceCandidateType; + +/** + * NiceCandidateTransport: + * @NICE_CANDIDATE_TRANSPORT_UDP: UDP transport + * @NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: TCP Active transport + * @NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: TCP Passive transport + * @NICE_CANDIDATE_TRANSPORT_TCP_SO: TCP Simultaneous-Open transport + * + * An enum representing the type of transport to use + */ +typedef enum +{ + NICE_CANDIDATE_TRANSPORT_UDP, + NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE, + NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE, + NICE_CANDIDATE_TRANSPORT_TCP_SO, +} NiceCandidateTransport; + +/** + * NiceRelayType: + * @NICE_RELAY_TYPE_TURN_UDP: A TURN relay using UDP + * @NICE_RELAY_TYPE_TURN_TCP: A TURN relay using TCP + * @NICE_RELAY_TYPE_TURN_TLS: A TURN relay using TLS over TCP + * + * An enum representing the type of relay to use + */ +typedef enum { + NICE_RELAY_TYPE_TURN_UDP, + NICE_RELAY_TYPE_TURN_TCP, + NICE_RELAY_TYPE_TURN_TLS +} NiceRelayType; + + +typedef struct _NiceCandidate NiceCandidate; + +typedef struct _TurnServer TurnServer; + +/** + * TurnServer: + * @ref_count: Reference count for the structure. + * @server: The #NiceAddress of the TURN server + * @username: The TURN username + * @password: The TURN password + * @decoded_username: The base64 decoded TURN username + * @decoded_password: The base64 decoded TURN password + * @decoded_username_len: The length of @decoded_username + * @decoded_password_len: The length of @decoded_password + * @type: The #NiceRelayType of the server + * + * A structure to store the TURN relay settings + */ +struct _TurnServer +{ + gint ref_count; + + NiceAddress server; + gchar *username; + gchar *password; + guint8 *decoded_username; + guint8 *decoded_password; + gsize decoded_username_len; + gsize decoded_password_len; + NiceRelayType type; +}; + +/** + * NiceCandidate: + * @type: The type of candidate + * @transport: The transport being used for the candidate + * @addr: The #NiceAddress of the candidate + * @base_addr: The #NiceAddress of the base address used by the candidate + * @priority: The priority of the candidate see note + * @stream_id: The ID of the stream to which belongs the candidate + * @component_id: The ID of the component to which belongs the candidate + * @foundation: The foundation of the candidate + * @username: The candidate-specific username to use (overrides the one set + * by nice_agent_set_local_credentials() or nice_agent_set_remote_credentials()) + * @password: The candidate-specific password to use (overrides the one set + * by nice_agent_set_local_credentials() or nice_agent_set_remote_credentials()) + * @turn: The #TurnServer settings if the candidate is + * of type %NICE_CANDIDATE_TYPE_RELAYED + * @sockptr: The underlying socket + * + * A structure to represent an ICE candidate + + + The @priority is an integer as specified in the ICE draft 19. If you are + using the MSN or the GOOGLE compatibility mode (which are based on ICE + draft 6, which uses a floating point qvalue as priority), then the @priority + value will represent the qvalue multiplied by 1000. + + + */ +struct _NiceCandidate +{ + NiceCandidateType type; + NiceCandidateTransport transport; + NiceAddress addr; + NiceAddress base_addr; + guint32 priority; + guint stream_id; + guint component_id; + gchar foundation[NICE_CANDIDATE_MAX_FOUNDATION]; + gchar *username; /* pointer to a nul-terminated username string */ + gchar *password; /* pointer to a nul-terminated password string */ + TurnServer *turn; + gpointer sockptr; +}; + +/** + * nice_candidate_new: + * @type: The #NiceCandidateType of the candidate to create + * + * Creates a new candidate. Must be freed with nice_candidate_free() + * + * Returns: A new #NiceCandidate + */ +NiceCandidate * +nice_candidate_new (NiceCandidateType type); + +/** + * nice_candidate_free: + * @candidate: The candidate to free + * + * Frees a #NiceCandidate + */ +void +nice_candidate_free (NiceCandidate *candidate); + +/** + * nice_candidate_copy: + * @candidate: The candidate to copy + * + * Makes a copy of a #NiceCandidate + * + * Returns: A new #NiceCandidate, a copy of @candidate + */ +NiceCandidate * +nice_candidate_copy (const NiceCandidate *candidate); + +/** + * nice_candidate_equal_target: + * @candidate1: A candidate + * @candidate2: A candidate + * + * Verifies that the candidates point to the same place, meaning they have + * the same transport and the same address. It ignores all other aspects. + * + * Returns: %TRUE if the candidates point to the same place + * + * Since: 0.1.15 + */ +gboolean +nice_candidate_equal_target (const NiceCandidate *candidate1, + const NiceCandidate *candidate2); + + GType nice_candidate_get_type (void); + +/** + * NICE_TYPE_CANDIDATE: + * + * A boxed type for a #NiceCandidate. + */ +#define NICE_TYPE_CANDIDATE nice_candidate_get_type () + +G_END_DECLS + +#endif /* __LIBNICE_CANDIDATE_H__ */ + diff --git a/linux_x86/include/nice/debug.h b/linux_x86/include/nice/debug.h new file mode 100644 index 0000000..c1a6473 --- /dev/null +++ b/linux_x86/include/nice/debug.h @@ -0,0 +1,105 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2008 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. + * + * 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 __LIBNICE_DEBUG_H__ +#define __LIBNICE_DEBUG_H__ + + +/** + * SECTION:debug + * @short_description: Debug messages utility functions + * @stability: Unstable + * + * Libnice can output a lot of information when debug messages are enabled. + * This can significantly help track down problems and/or understand what + * it's doing. + * + * You can enable/disable the debug messages by calling nice_debug_enable() + * or nice_debug_disable() and choosing whether you want only ICE debug messages + * or also stun debug messages. + * + * By default, the debug messages are disabled, unless the environment + * variable NICE_DEBUG is set, in which case, it must contain a comma separated + * list of flags specifying which debug to enable. + * The currently available flags are "nice", "stun", "pseudotcp", + * "pseudotcp-verbose" or "all" to enable all debug messages. + * If the 'pseudotcp' flag is enabled, then 'pseudotcp-verbose' gets + * automatically disabled. This is to allow the use of the 'all' flag without + * having verbose messages from pseudotcp. You can enable verbose debug messages + * from the pseudotcp layer by specifying 'pseudotcp-verbose' without the + * 'pseudotcp' flag. + * + * + * This API is unstable and is subject to change at any time... + * More flags are to come and a better API to enable/disable each flag + * should be added. + */ + + +#include + +G_BEGIN_DECLS + +/** + * nice_debug_enable: + * @with_stun: Also enable STUN debugging messages + * + * Enables libnice debug output to the terminal. Note that the + * `G_MESSAGES_DEBUG` and `NICE_DEBUG` environment variables must be set to the + * set of logging domains to print, in order for any output to be printed. Set + * them to `all` to print all debugging messages, or any of the following + * domains: + * - `libnice-stun` + * - `libnice-tests` + * - `libnice-socket` + * - `libnice` + * - `libnice-pseudotcp` + * - `libnice-pseudotcp-verbose` + */ +void nice_debug_enable (gboolean with_stun); + +/** + * nice_debug_disable: + * @with_stun: Also disable stun debugging messages + * + * Disables libnice debug output to the terminal + */ +void nice_debug_disable (gboolean with_stun); + +G_END_DECLS + +#endif /* __LIBNICE_DEBUG_H__ */ + diff --git a/linux_x86/include/nice/interfaces.h b/linux_x86/include/nice/interfaces.h new file mode 100644 index 0000000..50c627e --- /dev/null +++ b/linux_x86/include/nice/interfaces.h @@ -0,0 +1,82 @@ +/* + * interfaces.h - Source for interface discovery code + * + * Farsight Helper functions + * Copyright (C) 2006 Youness Alaoui + * Copyright (C) 2008-2009 Collabora, Nokia + * Contact: Youness Alaoui + * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __LIBNICE_INTERFACES_H__ +#define __LIBNICE_INTERFACES_H__ + +/** + * SECTION:interfaces + * @short_description: Utility functions to discover local network interfaces + * @include: interfaces.h + * @stability: Stable + * + * These utility functions allow the discovery of local network interfaces + * in a portable manner, they also allow finding the local ip addresses or + * the address allocated to a network interface. + */ + +#include + +G_BEGIN_DECLS + + +/** + * nice_interfaces_get_ip_for_interface: + * @interface_name: name of local interface + * + * Retrieves the IP address of an interface by its name. If this fails, %NULL + * is returned. + * + * Returns: (nullable) (transfer full): a newly-allocated string with the IP + * address + */ +gchar * nice_interfaces_get_ip_for_interface (gchar *interface_name); + + +/** + * nice_interfaces_get_local_ips: + * @include_loopback: Include any loopback devices + * + * Get a list of local ipv4 interface addresses + * + * Returns: (element-type utf8) (transfer full): a newly-allocated #GList of + * strings. The caller must free it. + */ + +GList * nice_interfaces_get_local_ips (gboolean include_loopback); + + +/** + * nice_interfaces_get_local_interfaces: + * + * Get the list of local interfaces + * + * Returns: (element-type utf8) (transfer full): a newly-allocated #GList of + * strings. The caller must free it. + */ +GList * nice_interfaces_get_local_interfaces (void); + +G_END_DECLS + +#endif /* __LIBNICE_INTERFACES_H__ */ diff --git a/linux_x86/include/nice/nice.h b/linux_x86/include/nice/nice.h new file mode 100644 index 0000000..5587ec4 --- /dev/null +++ b/linux_x86/include/nice/nice.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2006-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2006-2009 Nokia Corporation. All rights reserved. + * Contact: Kai Vehmanen + * + * 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: + * Dafydd Harries, Collabora Ltd. + * 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 _NICE_H +#define _NICE_H + +#include "agent.h" +#include "interfaces.h" + +#endif /* _NICE_H */ + diff --git a/linux_x86/include/nice/pseudotcp.h b/linux_x86/include/nice/pseudotcp.h new file mode 100644 index 0000000..e087ddc --- /dev/null +++ b/linux_x86/include/nice/pseudotcp.h @@ -0,0 +1,599 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2010, 2014 Collabora Ltd. + * Contact: Philip Withnall + + * + * 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. + * Philip Withnall, 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 __LIBNICE_PSEUDOTCP_H__ +#define __LIBNICE_PSEUDOTCP_H__ + +/** + * SECTION:pseudotcp + * @short_description: Pseudo TCP implementation + * @include: pseudotcp.h + * @stability: Stable + * + * The #PseudoTcpSocket is an object implementing a Pseudo Tcp Socket for use + * over UDP. + * The socket will implement a subset of the TCP stack to allow for a reliable + * transport over non-reliable sockets (such as UDP). + * + * See the file tests/test-pseudotcp.c in the source package for an example + * of how to use the object. + * + * Since: 0.0.11 + */ + + + +#include + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +# include + +#ifndef ECONNABORTED +# define ECONNABORTED WSAECONNABORTED +#endif + +#ifndef ENOTCONN +# define ENOTCONN WSAENOTCONN +#endif + +#ifndef EWOULDBLOCK +# define EWOULDBLOCK WSAEWOULDBLOCK +#endif + +#ifndef ECONNRESET +# define ECONNRESET WSAECONNRESET +#endif + +#ifndef EMSGSIZE +# define EMSGSIZE WSAEMSGSIZE +#endif + +#ifndef ETIMEDOUT +# define ETIMEDOUT WSAETIMEDOUT +#endif +#endif +#endif + +#include "agent.h" + +G_BEGIN_DECLS + +/** + * PseudoTcpSocket: + * + * The #PseudoTcpSocket is the GObject implementing the Pseudo TCP Socket + * + * Since: 0.0.11 + */ +typedef struct _PseudoTcpSocket PseudoTcpSocket; + +typedef struct _PseudoTcpSocketClass PseudoTcpSocketClass; + +GType pseudo_tcp_socket_get_type (void); + +/* TYPE MACROS */ +#define PSEUDO_TCP_SOCKET_TYPE \ + (pseudo_tcp_socket_get_type ()) +#define PSEUDO_TCP_SOCKET(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), PSEUDO_TCP_SOCKET_TYPE, \ + PseudoTcpSocket)) +#define PSEUDO_TCP_SOCKET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), PSEUDO_TCP_SOCKET_TYPE, \ + PseudoTcpSocketClass)) +#define IS_PSEUDO_TCP_SOCKET(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), PSEUDO_TCP_SOCKET_TYPE)) +#define IS_PSEUDO_TCP_SOCKET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), PSEUDO_TCP_SOCKET_TYPE)) +#define PSEUDOTCP_SOCKET_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), PSEUDO_TCP_SOCKET_TYPE, \ + PseudoTcpSocketClass)) + +/** + * PseudoTcpDebugLevel: + * @PSEUDO_TCP_DEBUG_NONE: Disable debug messages + * @PSEUDO_TCP_DEBUG_NORMAL: Enable basic debug messages + * @PSEUDO_TCP_DEBUG_VERBOSE: Enable verbose debug messages + * + * Valid values of debug levels to be set. + * + * Since: 0.0.11 + */ +typedef enum { + PSEUDO_TCP_DEBUG_NONE = 0, + PSEUDO_TCP_DEBUG_NORMAL, + PSEUDO_TCP_DEBUG_VERBOSE, +} PseudoTcpDebugLevel; + +/** + * PseudoTcpState: + * @PSEUDO_TCP_LISTEN: The socket's initial state. The socket isn't connected and is + * listening for an incoming connection + * @PSEUDO_TCP_SYN_SENT: The socket has sent a connection request (SYN) packet and is + * waiting for an answer + * @PSEUDO_TCP_SYN_RECEIVED: The socket has received a connection request (SYN) packet. + * @PSEUDO_TCP_ESTABLISHED: The socket is connected + * @PSEUDO_TCP_CLOSED: The socket has been closed + * @PSEUDO_TCP_FIN_WAIT_1: The socket has been closed locally but not remotely + * (Since: 0.1.8) + * @PSEUDO_TCP_FIN_WAIT_2: The socket has been closed locally but not remotely + * (Since: 0.1.8) + * @PSEUDO_TCP_CLOSING: The socket has been closed locally and remotely + * (Since: 0.1.8) + * @PSEUDO_TCP_TIME_WAIT: The socket has been closed locally and remotely + * (Since: 0.1.8) + * @PSEUDO_TCP_CLOSE_WAIT: The socket has been closed remotely but not locally + * (Since: 0.1.8) + * @PSEUDO_TCP_LAST_ACK: The socket has been closed locally and remotely + * (Since: 0.1.8) + * + * An enum representing the state of the #PseudoTcpSocket. These states + * correspond to the TCP states in RFC 793. + * See also: #PseudoTcpSocket:state + * + * Since: 0.0.11 + */ +typedef enum { + PSEUDO_TCP_LISTEN, + PSEUDO_TCP_SYN_SENT, + PSEUDO_TCP_SYN_RECEIVED, + PSEUDO_TCP_ESTABLISHED, + PSEUDO_TCP_CLOSED, + PSEUDO_TCP_FIN_WAIT_1, + PSEUDO_TCP_FIN_WAIT_2, + PSEUDO_TCP_CLOSING, + PSEUDO_TCP_TIME_WAIT, + PSEUDO_TCP_CLOSE_WAIT, + PSEUDO_TCP_LAST_ACK, +} PseudoTcpState; + +/** + * PseudoTcpWriteResult: + * @WR_SUCCESS: The write operation was successful + * @WR_TOO_LARGE: The socket type requires that message be sent atomically + * and the size of the message to be sent made this impossible. + * @WR_FAIL: There was an error sending the message + * + * An enum representing the result value of the write operation requested by + * the #PseudoTcpSocket. + * See also: %PseudoTcpCallbacks:WritePacket + * + * Since: 0.0.11 + */ +typedef enum { + WR_SUCCESS, + WR_TOO_LARGE, + WR_FAIL +} PseudoTcpWriteResult; + +/** + * PseudoTcpShutdown: + * @PSEUDO_TCP_SHUTDOWN_RD: Shut down the local reader only + * @PSEUDO_TCP_SHUTDOWN_WR: Shut down the local writer only + * @PSEUDO_TCP_SHUTDOWN_RDWR: Shut down both reading and writing + * + * Options for which parts of a connection to shut down when calling + * pseudo_tcp_socket_shutdown(). These correspond to the values passed to POSIX + * shutdown(). + * + * Since: 0.1.8 + */ +typedef enum { + PSEUDO_TCP_SHUTDOWN_RD, + PSEUDO_TCP_SHUTDOWN_WR, + PSEUDO_TCP_SHUTDOWN_RDWR, +} PseudoTcpShutdown; + +/** + * PseudoTcpCallbacks: + * @user_data: A user defined pointer to be passed to the callbacks + * @PseudoTcpOpened: The #PseudoTcpSocket is now connected + * @PseudoTcpReadable: The socket is readable + * @PseudoTcpWritable: The socket is writable + * @PseudoTcpClosed: The socket was closed (both sides) + * @WritePacket: This callback is called when the socket needs to send data. + * + * A structure containing callbacks functions that will be called by the + * #PseudoTcpSocket when some events happen. + * See also: #PseudoTcpWriteResult + * + * Since: 0.0.11 + */ +typedef struct { + gpointer user_data; + void (*PseudoTcpOpened) (PseudoTcpSocket *tcp, gpointer data); + void (*PseudoTcpReadable) (PseudoTcpSocket *tcp, gpointer data); + void (*PseudoTcpWritable) (PseudoTcpSocket *tcp, gpointer data); + void (*PseudoTcpClosed) (PseudoTcpSocket *tcp, guint32 error, gpointer data); + PseudoTcpWriteResult (*WritePacket) (PseudoTcpSocket *tcp, + const gchar * buffer, guint32 len, gpointer data); +} PseudoTcpCallbacks; + +/** + * pseudo_tcp_socket_new: + * @conversation: The conversation id for the socket. + * @callbacks: A pointer to the #PseudoTcpCallbacks structure for getting + * notified of the #PseudoTcpSocket events. + * + * Creates a new #PseudoTcpSocket for the specified conversation + * + + + The @callbacks must be non-NULL, in order to get notified of packets the + socket needs to send. + + + If the @callbacks structure was dynamicly allocated, it can be freed + after the call @pseudo_tcp_socket_new + + + * + * Returns: The new #PseudoTcpSocket object, %NULL on error + * + * Since: 0.0.11 + */ +PseudoTcpSocket *pseudo_tcp_socket_new (guint32 conversation, + PseudoTcpCallbacks *callbacks); + + +/** + * pseudo_tcp_socket_connect: + * @self: The #PseudoTcpSocket object. + * + * Connects the #PseudoTcpSocket to the peer with the same conversation id. + * The connection will only be successful after the + * %PseudoTcpCallbacks:PseudoTcpOpened callback is called + * + * Returns: %TRUE on success, %FALSE on failure (not in %TCP_LISTEN state) + * See also: pseudo_tcp_socket_get_error() + * + * Since: 0.0.11 + */ +gboolean pseudo_tcp_socket_connect(PseudoTcpSocket *self); + + +/** + * pseudo_tcp_socket_recv: + * @self: The #PseudoTcpSocket object. + * @buffer: The buffer to fill with received data + * @len: The length of @buffer + * + * Receive data from the socket. + * + + + Only call this on the %PseudoTcpCallbacks:PseudoTcpReadable callback. + + + This function should be called in a loop. If this function does not + return -1 with EWOULDBLOCK as the error, the + %PseudoTcpCallbacks:PseudoTcpReadable callback will not be called again. + + + * + * Returns: The number of bytes received or -1 in case of error + * See also: pseudo_tcp_socket_get_error() + * + * Since: 0.0.11 + */ +gint pseudo_tcp_socket_recv(PseudoTcpSocket *self, char * buffer, size_t len); + + +/** + * pseudo_tcp_socket_send: + * @self: The #PseudoTcpSocket object. + * @buffer: The buffer with data to send + * @len: The length of @buffer + * + * Send data on the socket. + * + + + If this function return -1 with EWOULDBLOCK as the error, or if the return + value is lower than @len, then the %PseudoTcpCallbacks:PseudoTcpWritable + callback will be called when the socket will become writable. + + + * + * Returns: The number of bytes sent or -1 in case of error + * See also: pseudo_tcp_socket_get_error() + * + * Since: 0.0.11 + */ +gint pseudo_tcp_socket_send(PseudoTcpSocket *self, const char * buffer, + guint32 len); + + +/** + * pseudo_tcp_socket_close: + * @self: The #PseudoTcpSocket object. + * @force: %TRUE to close the socket forcefully, %FALSE to close it gracefully + * + * Close the socket for sending. If @force is set to %FALSE, the socket will + * finish sending pending data before closing. If it is set to %TRUE, the socket + * will discard pending data and close the connection immediately (sending a TCP + * RST segment). + * + * The socket will be closed in both directions – sending and receiving – and + * any pending received data must be read before calling this function, by + * calling pseudo_tcp_socket_recv() until it blocks. If any pending data is in + * the receive buffer when pseudo_tcp_socket_close() is called, a TCP RST + * segment will be sent to the peer to notify it of the data loss. + * + + + The %PseudoTcpCallbacks:PseudoTcpClosed callback will not be called once + the socket gets closed. It is only used for aborted connection. + Instead, the socket gets closed when the pseudo_tcp_socket_get_next_clock() + function returns FALSE. + + + * + * See also: pseudo_tcp_socket_get_next_clock() + * + * Since: 0.0.11 + */ +void pseudo_tcp_socket_close(PseudoTcpSocket *self, gboolean force); + +/** + * pseudo_tcp_socket_shutdown: + * @self: The #PseudoTcpSocket object. + * @how: The directions of the connection to shut down. + * + * Shut down sending, receiving, or both on the socket, depending on the value + * of @how. The behaviour of pseudo_tcp_socket_send() and + * pseudo_tcp_socket_recv() will immediately change after this function returns + * (depending on the value of @how), though the socket may continue to process + * network traffic in the background even if sending or receiving data is + * forbidden. + * + * This is equivalent to the POSIX shutdown() function. Setting @how to + * %PSEUDO_TCP_SHUTDOWN_RDWR is equivalent to calling pseudo_tcp_socket_close(). + * + * Since: 0.1.8 + */ +void pseudo_tcp_socket_shutdown (PseudoTcpSocket *self, PseudoTcpShutdown how); + +/** + * pseudo_tcp_socket_get_error: + * @self: The #PseudoTcpSocket object. + * + * Return the last encountered error. + * + + + The return value can be : + + EINVAL (for pseudo_tcp_socket_connect()). + + + EWOULDBLOCK or ENOTCONN (for pseudo_tcp_socket_recv() and + pseudo_tcp_socket_send()). + + + + * + * Returns: The error code + * See also: pseudo_tcp_socket_connect() + * See also: pseudo_tcp_socket_recv() + * See also: pseudo_tcp_socket_send() + * + * Since: 0.0.11 + */ +int pseudo_tcp_socket_get_error(PseudoTcpSocket *self); + + +/** + * pseudo_tcp_socket_get_next_clock: + * @self: The #PseudoTcpSocket object. + * @timeout: A pointer to be filled with the new timeout. + * + * Call this to determine the timeout needed before the next time call + * to pseudo_tcp_socket_notify_clock() should be made. + * + * Returns: %TRUE if @timeout was filled, %FALSE if the socket is closed and + * ready to be destroyed. + * + * See also: pseudo_tcp_socket_notify_clock() + * + * Since: 0.0.11 + */ +gboolean pseudo_tcp_socket_get_next_clock(PseudoTcpSocket *self, + guint64 *timeout); + + +/** + * pseudo_tcp_socket_notify_clock: + * @self: The #PseudoTcpSocket object. + * + * Start the processing of receiving data, pending data or syn/acks. + * Call this based on timeout value returned by + * pseudo_tcp_socket_get_next_clock(). + * It's ok to call this too frequently. + * + * See also: pseudo_tcp_socket_get_next_clock() + * + * Since: 0.0.11 + */ +void pseudo_tcp_socket_notify_clock(PseudoTcpSocket *self); + + +/** + * pseudo_tcp_socket_notify_mtu: + * @self: The #PseudoTcpSocket object. + * @mtu: The new MTU of the socket + * + * Set the MTU of the socket + * + * Since: 0.0.11 + */ +void pseudo_tcp_socket_notify_mtu(PseudoTcpSocket *self, guint16 mtu); + + +/** + * pseudo_tcp_socket_notify_packet: + * @self: The #PseudoTcpSocket object. + * @buffer: The buffer containing the received data + * @len: The length of @buffer + * + * Notify the #PseudoTcpSocket when a new packet arrives + * + * Returns: %TRUE if the packet was processed successfully, %FALSE otherwise + * + * Since: 0.0.11 + */ +gboolean pseudo_tcp_socket_notify_packet(PseudoTcpSocket *self, + const gchar * buffer, guint32 len); + + +/** + * pseudo_tcp_socket_notify_message: + * @self: The #PseudoTcpSocket object. + * @message: A #NiceInputMessage containing the received data. + * + * Notify the #PseudoTcpSocket that a new message has arrived, and enqueue the + * data in its buffers to the #PseudoTcpSocket’s receive buffer. + * + * Returns: %TRUE if the packet was processed successfully, %FALSE otherwise + * + * Since: 0.1.5 + */ +gboolean pseudo_tcp_socket_notify_message (PseudoTcpSocket *self, + NiceInputMessage *message); + + +/** + * pseudo_tcp_set_debug_level: + * @level: The level of debug to set + * + * Sets the debug level to enable/disable normal/verbose debug messages. + * + * Since: 0.0.11 + */ +void pseudo_tcp_set_debug_level (PseudoTcpDebugLevel level); + + +/** + * pseudo_tcp_socket_get_available_bytes: + * @self: The #PseudoTcpSocket object. + * + * Gets the number of bytes of data in the buffer that can be read without + * receiving more packets from the network. + * + * Returns: The number of bytes or -1 if the connection is not established + * + * Since: 0.1.5 + */ + +gint pseudo_tcp_socket_get_available_bytes (PseudoTcpSocket *self); + +/** + * pseudo_tcp_socket_can_send: + * @self: The #PseudoTcpSocket object. + * + * Returns if there is space in the send buffer to send any data. + * + * Returns: %TRUE if data can be sent, %FALSE otherwise + * + * Since: 0.1.5 + */ + +gboolean pseudo_tcp_socket_can_send (PseudoTcpSocket *self); + +/** + * pseudo_tcp_socket_get_available_send_space: + * @self: The #PseudoTcpSocket object. + * + * Gets the number of bytes of space available in the transmission buffer. + * + * Returns: The number of bytes, or 0 if the connection is not established. + * + * Since: 0.1.5 + */ +gsize pseudo_tcp_socket_get_available_send_space (PseudoTcpSocket *self); + +/** + * pseudo_tcp_socket_set_time: + * @self: The #PseudoTcpSocket object. + * @current_time: Current monotonic time, in milliseconds; or zero to use the + * system monotonic clock. + * + * Sets the current monotonic time to be used by the TCP socket when calculating + * timeouts and expiry times. If this function is not called, or is called with + * @current_time as zero, g_get_monotonic_time() will be used. Otherwise, the + * specified @current_time will be used until it is updated by calling this + * function again. + * + * This function is intended for testing only, and should not be used in + * production code. + * + * Since: 0.1.8 + */ +void pseudo_tcp_socket_set_time (PseudoTcpSocket *self, guint32 current_time); + +/** + * pseudo_tcp_socket_is_closed: + * @self: The #PseudoTcpSocket object. + * + * Gets whether the socket is closed, with the shutdown handshake completed, + * and both peers no longer able to read or write data to the connection. + * + * Returns: %TRUE if the socket is closed in both directions, %FALSE otherwise + * Since: 0.1.8 + */ +gboolean pseudo_tcp_socket_is_closed (PseudoTcpSocket *self); + +/** + * pseudo_tcp_socket_is_closed_remotely: + * @self: The #PseudoTcpSocket object. + * + * Gets whether the socket has been closed on the remote peer’s side of the + * connection (i.e. whether pseudo_tcp_socket_close() has been called there). + * This is guaranteed to return %TRUE if pseudo_tcp_socket_is_closed() returns + * %TRUE. It will not return %TRUE after pseudo_tcp_socket_close() is called + * until a FIN segment is received from the remote peer. + * + * Returns: %TRUE if the remote peer has closed its side of the connection, + * %FALSE otherwise + * Since: 0.1.8 + */ +gboolean pseudo_tcp_socket_is_closed_remotely (PseudoTcpSocket *self); + +G_END_DECLS + +#endif /* __LIBNICE_PSEUDOTCP_H__ */ + diff --git a/linux_x86/include/stun/constants.h b/linux_x86/include/stun/constants.h new file mode 100644 index 0000000..29e1cec --- /dev/null +++ b/linux_x86/include/stun/constants.h @@ -0,0 +1,203 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2008 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. + * + * 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 _STUN_CONSTANTS_H +#define _STUN_CONSTANTS_H + + +/** + * SECTION:stunconstants + * @short_description: STUN constants + * @include: stun/constants.h + * @stability: Stable + * + * Various constants defining parts of the STUN and TURN protocols and + * on-the-wire packet formats. + */ + +/** + * STUN_ATTRIBUTE_LENGTH_LEN: + * + * Length of the length field of a STUN attribute (in bytes). + */ +/** + * STUN_ATTRIBUTE_LENGTH_POS: + * + * Offset of the length field of a STUN attribute (in bytes). + */ +/** + * STUN_ATTRIBUTE_TYPE_LEN: + * + * Length of the type field of a STUN attribute (in bytes). + */ +/** + * STUN_ATTRIBUTE_TYPE_POS: + * + * Offset of the type field of a STUN attribute (in bytes). + */ +/** + * STUN_ATTRIBUTE_VALUE_POS: + * + * Offset of the value field of a STUN attribute (in bytes). + */ +/** + * STUN_ID_LEN: + * + * Length of the ID field of a STUN message (in bytes). + */ +/** + * STUN_MAGIC_COOKIE: + * + * Magic cookie value used to identify STUN messages. + */ +/** + * TURN_MAGIC_COOKIE: + * + * Magic cookie value used to identify TURN messages. + */ +/** + * STUN_MAX_MESSAGE_SIZE_IPV4: + * + * Maximum size of a STUN message sent over IPv4 (in bytes). + */ +/** + * STUN_MAX_MESSAGE_SIZE_IPV6: + * + * Maximum size of a STUN message sent over IPv6 (in bytes). + */ +/** + * STUN_MESSAGE_ATTRIBUTES_POS: + * + * Offset of the attributes of a STUN message (in bytes). + */ +/** + * STUN_MESSAGE_HEADER_LENGTH: + * + * Total length of a STUN message header (in bytes). + */ +/** + * STUN_MESSAGE_LENGTH_LEN: + * + * Length of the length field of a STUN message (in bytes). + */ +/** + * STUN_MESSAGE_LENGTH_POS: + * + * Offset of the length field of a STUN message (in bytes). + */ +/** + * STUN_MESSAGE_TRANS_ID_LEN: + * + * Length of the transaction ID field of a STUN message (in bytes). + */ +/** + * STUN_MESSAGE_TRANS_ID_POS: + * + * Offset of the transaction ID field of a STUN message (in bytes). + */ +/** + * STUN_MESSAGE_TYPE_LEN: + * + * Length of the type field of a STUN message (in bytes). + */ +/** + * STUN_MESSAGE_TYPE_POS: + * + * Offset of the type field of a STUN message (in bytes). + */ + +#define STUN_MESSAGE_TYPE_POS 0 +#define STUN_MESSAGE_TYPE_LEN 2 +#define STUN_MESSAGE_LENGTH_POS \ + (STUN_MESSAGE_TYPE_POS + STUN_MESSAGE_TYPE_LEN) +#define STUN_MESSAGE_LENGTH_LEN 2 +#define STUN_MESSAGE_TRANS_ID_POS \ + (STUN_MESSAGE_LENGTH_POS + STUN_MESSAGE_LENGTH_LEN) +#define STUN_MESSAGE_TRANS_ID_LEN 16 +#define STUN_MESSAGE_ATTRIBUTES_POS \ + (STUN_MESSAGE_TRANS_ID_POS + STUN_MESSAGE_TRANS_ID_LEN) + +#define STUN_MESSAGE_HEADER_LENGTH STUN_MESSAGE_ATTRIBUTES_POS + +#define STUN_ATTRIBUTE_TYPE_POS 0 +#define STUN_ATTRIBUTE_TYPE_LEN 2 +#define STUN_ATTRIBUTE_LENGTH_POS \ + (STUN_ATTRIBUTE_TYPE_POS + STUN_ATTRIBUTE_TYPE_LEN) +#define STUN_ATTRIBUTE_LENGTH_LEN 2 +#define STUN_ATTRIBUTE_VALUE_POS \ + (STUN_ATTRIBUTE_LENGTH_POS + STUN_ATTRIBUTE_LENGTH_LEN) + +/** + * STUN_ATTRIBUTE_HEADER_LENGTH: + * + * Length of a single STUN attribute header (in bytes). + */ +#define STUN_ATTRIBUTE_HEADER_LENGTH STUN_ATTRIBUTE_VALUE_POS + + +#define STUN_MAX_MESSAGE_SIZE_IPV4 576 +#define STUN_MAX_MESSAGE_SIZE_IPV6 1280 +/* #define STUN_MAX_MESSAGE_SIZE STUN_MAX_MESSAGE_SIZE_IPV4 */ + +#define STUN_ID_LEN 16 + +/** + * STUN_AGENT_MAX_SAVED_IDS: + * + * Maximum number of simultaneously ongoing STUN transactions. + */ +#define STUN_AGENT_MAX_SAVED_IDS 200 + +/** + * STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES: + * + * Maximum number of unknown attribute which can be handled in a single STUN + * message. + */ +#define STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES 256 + +#define STUN_MAGIC_COOKIE 0x2112A442 +#define TURN_MAGIC_COOKIE 0x72c64bc6 + +#ifndef TRUE +#define TRUE (1 == 1) +#endif + +#ifndef FALSE +#define FALSE (0 == 1) +#endif + +#endif /* _STUN_CONSTANTS_H */ diff --git a/linux_x86/include/stun/debug.h b/linux_x86/include/stun/debug.h new file mode 100644 index 0000000..47a6114 --- /dev/null +++ b/linux_x86/include/stun/debug.h @@ -0,0 +1,102 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2007 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. + * + * 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 STUN_DEBUG_H +#define STUN_DEBUG_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * stun_debug_enable: + * + * Enable debug messages to stderr + */ +void stun_debug_enable (void); + +/** + * stun_debug_disable: + * + * Disable debug messages to stderr + */ +void stun_debug_disable (void); + +/** + * StunDebugHandler: + * @format: printf()-style debug message format string + * @ap: Parameters to substitute into message placeholders + * + * Callback for a debug message from the STUN code. + */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)) +typedef void (*StunDebugHandler) (const char *format, va_list ap) + __attribute__((__format__ (__printf__, 1, 0))); +#else +typedef void (*StunDebugHandler) (const char *format, va_list ap); +#endif + +/** + * stun_set_debug_handler: + * @handler: (nullable): Handler for STUN debug messages, or %NULL to use the + * default + * + * Set a callback function to be invoked for each debug message from the STUN + * code. The callback will only be invoked if STUN debugging is enabled using + * stun_debug_enable(). + * + * The default callback prints the formatted debug message to stderr. + */ +void stun_set_debug_handler (StunDebugHandler handler); + +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)) +void stun_debug (const char *fmt, ...) + __attribute__((__format__ (__printf__, 1, 2))); +#else +void stun_debug (const char *fmt, ...); +#endif +void stun_debug_bytes (const char *prefix, const void *data, size_t len); + + +# ifdef __cplusplus +} +# endif + +#endif /* STUN_DEBUG_H */ diff --git a/linux_x86/include/stun/stunagent.h b/linux_x86/include/stun/stunagent.h new file mode 100644 index 0000000..95e89fd --- /dev/null +++ b/linux_x86/include/stun/stunagent.h @@ -0,0 +1,521 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008-2009 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. + * + * 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 _STUN_AGENT_H +#define _STUN_AGENT_H + +/** + * SECTION:stunagent + * @short_description: STUN agent for building and validating STUN messages + * @include: stun/stunagent.h + * @see_also: #StunMessage + * @stability: Stable + * + * The STUN Agent allows you to create and validate STUN messages easily. + * It's main purpose is to make sure the building and validation methods used + * are compatible with the RFC you create it with. It also tracks the transaction + * ids of the requests you send, so you can validate if a STUN response you + * received should be processed by that agent or not. + * + */ + + +#ifdef _WIN32 +#include "win32_common.h" +#else +#include +#endif + +#include +#include + +/** + * StunAgent: + * + * An opaque structure representing the STUN agent. + */ +typedef struct stun_agent_t StunAgent; + +#include "stunmessage.h" +#include "debug.h" + +/** + * StunCompatibility: + * @STUN_COMPATIBILITY_RFC3489: Use the STUN specifications compatible with + * RFC 3489 + * @STUN_COMPATIBILITY_RFC5389: Use the STUN specifications compatible with + * RFC 5389 + * @STUN_COMPATIBILITY_MSICE2: Use the STUN specifications compatible with + * [MS-ICE2] (a mix between RFC3489 and RFC5389) + * @STUN_COMPATIBILITY_OC2007: Use the STUN specifications compatible with + * Microsoft Office Communicator 2007 (basically RFC3489 with swapped + * REALM and NONCE attribute hex IDs, attributes are not aligned) + * @STUN_COMPATIBILITY_WLM2009: An alias for @STUN_COMPATIBILITY_MSICE2 + * @STUN_COMPATIBILITY_LAST: Dummy last compatibility mode + * + * Enum that specifies the STUN compatibility mode of the #StunAgent + * + * @STUN_COMPATIBILITY_WLM2009 is deprecated and should not be used + * in newly-written code. It is kept for compatibility reasons and represents + * the same compatibility as @STUN_COMPATIBILITY_MSICE2. + */ +typedef enum { + STUN_COMPATIBILITY_RFC3489, + STUN_COMPATIBILITY_RFC5389, + STUN_COMPATIBILITY_MSICE2, + STUN_COMPATIBILITY_OC2007, + STUN_COMPATIBILITY_WLM2009 = STUN_COMPATIBILITY_MSICE2, + STUN_COMPATIBILITY_LAST = STUN_COMPATIBILITY_OC2007 +} StunCompatibility; + + +/** + * StunValidationStatus: + * @STUN_VALIDATION_SUCCESS: The message is validated + * @STUN_VALIDATION_NOT_STUN: This is not a valid STUN message + * @STUN_VALIDATION_INCOMPLETE_STUN: The message seems to be valid but incomplete + * @STUN_VALIDATION_BAD_REQUEST: The message does not have the cookie or the + * fingerprint while the agent needs it with its usage + * @STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST: The message is valid but + * unauthorized with no username and message-integrity attributes. + * A BAD_REQUEST error must be generated + * @STUN_VALIDATION_UNAUTHORIZED: The message is valid but unauthorized as + * the username/password do not match. + * An UNAUTHORIZED error must be generated + * @STUN_VALIDATION_UNMATCHED_RESPONSE: The message is valid but this is a + * response/error that doesn't match a previously sent request + * @STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE: The message is valid but + * contains one or more unknown comprehension attributes. + * stun_agent_build_unknown_attributes_error() should be called + * @STUN_VALIDATION_UNKNOWN_ATTRIBUTE: The message is valid but contains one + * or more unknown comprehension attributes. This is a response, or error, + * or indication message and no error response should be sent + * + * This enum is used as the return value of stun_agent_validate() and represents + * the status result of the validation of a STUN message. + */ +typedef enum { + STUN_VALIDATION_SUCCESS, + STUN_VALIDATION_NOT_STUN, + STUN_VALIDATION_INCOMPLETE_STUN, + STUN_VALIDATION_BAD_REQUEST, + STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST, + STUN_VALIDATION_UNAUTHORIZED, + STUN_VALIDATION_UNMATCHED_RESPONSE, + STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE, + STUN_VALIDATION_UNKNOWN_ATTRIBUTE, +} StunValidationStatus; + +/** + * StunAgentUsageFlags: + * @STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS: The agent should be using the short + * term credentials mechanism for authenticating STUN messages + * @STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS: The agent should be using the long + * term credentials mechanism for authenticating STUN messages + * @STUN_AGENT_USAGE_USE_FINGERPRINT: The agent should add the FINGERPRINT + * attribute to the STUN messages it creates. + * @STUN_AGENT_USAGE_ADD_SOFTWARE: The agent should add the SOFTWARE attribute + * to the STUN messages it creates. Calling nice_agent_set_software() will have + * the same effect as enabling this Usage. STUN Indications do not have the + * SOFTWARE attributes added to them though. The SOFTWARE attribute is only + * added for the RFC5389 and MSICE2 compatibility modes. + * @STUN_AGENT_USAGE_IGNORE_CREDENTIALS: The agent should ignore any credentials + * in the STUN messages it receives (the MESSAGE-INTEGRITY attribute + * will never be validated by stun_agent_validate()) + * @STUN_AGENT_USAGE_NO_INDICATION_AUTH: The agent should ignore credentials + * in the STUN messages it receives if the #StunClass of the message is + * #STUN_INDICATION (some implementation require #STUN_INDICATION messages to + * be authenticated, while others never add a MESSAGE-INTEGRITY attribute to a + * #STUN_INDICATION message) + * @STUN_AGENT_USAGE_FORCE_VALIDATER: The agent should always try to validate + * the password of a STUN message, even if it already knows what the password + * should be (a response to a previously created request). This means that the + * #StunMessageIntegrityValidate callback will always be called when there is + * a MESSAGE-INTEGRITY attribute. + * @STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES: The agent should not assume STUN + * attributes are aligned on 32-bit boundaries when parsing messages and also + * do not add padding when creating messages. + * + * This enum defines a bitflag usages for a #StunAgent and they will define how + * the agent should behave, independently of the compatibility mode it uses. + * See also: stun_agent_init() + * See also: stun_agent_validate() + */ +typedef enum { + STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS = (1 << 0), + STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS = (1 << 1), + STUN_AGENT_USAGE_USE_FINGERPRINT = (1 << 2), + STUN_AGENT_USAGE_ADD_SOFTWARE = (1 << 3), + STUN_AGENT_USAGE_IGNORE_CREDENTIALS = (1 << 4), + STUN_AGENT_USAGE_NO_INDICATION_AUTH = (1 << 5), + STUN_AGENT_USAGE_FORCE_VALIDATER = (1 << 6), + STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES = (1 << 7), +} StunAgentUsageFlags; + + +typedef struct { + StunTransactionId id; + StunMethod method; + uint8_t *key; + size_t key_len; + uint8_t long_term_key[16]; + bool long_term_valid; + bool valid; +} StunAgentSavedIds; + +struct stun_agent_t { + StunCompatibility compatibility; + StunAgentSavedIds sent_ids[STUN_AGENT_MAX_SAVED_IDS]; + uint16_t *known_attributes; + StunAgentUsageFlags usage_flags; + const char *software_attribute; + bool ms_ice2_send_legacy_connchecks; +}; + +/** + * StunDefaultValidaterData: + * @username: The username + * @username_len: The length of the @username + * @password: The password + * @password_len: The length of the @password + * + * This structure is used as an element of the user_data to the + * stun_agent_default_validater() function for authenticating a STUN + * message during validationg. + * See also: stun_agent_default_validater() + */ +typedef struct { + uint8_t *username; + size_t username_len; + uint8_t *password; + size_t password_len; +} StunDefaultValidaterData; + + +/** + * StunMessageIntegrityValidate: + * @agent: The #StunAgent + * @message: The #StunMessage being validated + * @username: The username found in the @message + * @username_len: The length of @username + * @password: The password associated with that username. This argument is a + * pointer to a byte array that must be set by the validater function. + * @password_len: The length of @password which must also be set by the + * validater function. + * @user_data: Data to give the function + * + * This is the prototype for the @validater argument of the stun_agent_validate() + * function. + * See also: stun_agent_validate() + * Returns: %TRUE if the authentication was successful, + * %FALSE if the authentication failed + */ +typedef bool (*StunMessageIntegrityValidate) (StunAgent *agent, + StunMessage *message, uint8_t *username, uint16_t username_len, + uint8_t **password, size_t *password_len, void *user_data); + +/** + * stun_agent_default_validater: + * @agent: The #StunAgent + * @message: The #StunMessage being validated + * @username: The username found in the @message + * @username_len: The length of @username + * @password: The password associated with that username. This argument is a + * pointer to a byte array that must be set by the validater function. + * @password_len: The length of @password which must also be set by the + * validater function. + * @user_data: This must be an array of #StunDefaultValidaterData structures. + * The last element in the array must have a username set to NULL + * + * This is a helper function to be used with stun_agent_validate(). If no + * complicated processing of the username needs to be done, this function can + * be used with stun_agent_validate() to quickly and easily match the username + * of a STUN message with its password. Its @user_data argument must be an array + * of #StunDefaultValidaterData which will allow us to map a username to a + * password + * See also: stun_agent_validate() + * Returns: %TRUE if the authentication was successful, + * %FALSE if the authentication failed + */ +bool stun_agent_default_validater (StunAgent *agent, + StunMessage *message, uint8_t *username, uint16_t username_len, + uint8_t **password, size_t *password_len, void *user_data); + +/** + * stun_agent_init: + * @agent: The #StunAgent to initialize + * @known_attributes: An array of #uint16_t specifying which attributes should + * be known by the agent. Any STUN message received that contains a mandatory + * attribute that is not in this array will yield a + * #STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE or a + * #STUN_VALIDATION_UNKNOWN_ATTRIBUTE error when calling stun_agent_validate() + * @compatibility: The #StunCompatibility to use for this agent. This will affect + * how the agent builds and validates the STUN messages + * @usage_flags: A bitflag using #StunAgentUsageFlags values to define which + * STUN usages the agent should use. + * + * This function must be called to initialize an agent before it is being used. + * + + + The @known_attributes data must exist in memory as long as the @agent is used + + + If the #STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS and + #STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS usage flags are not set, then the + agent will default in using the short term credentials mechanism + + + The #STUN_AGENT_USAGE_USE_FINGERPRINT and #STUN_AGENT_USAGE_ADD_SOFTWARE + usage flags are only valid if the #STUN_COMPATIBILITY_RFC5389 or + #STUN_COMPATIBILITY_MSICE2 @compatibility is used + + + */ +void stun_agent_init (StunAgent *agent, const uint16_t *known_attributes, + StunCompatibility compatibility, StunAgentUsageFlags usage_flags); + +/** + * stun_agent_validate: + * @agent: The #StunAgent + * @msg: The #StunMessage to build + * @buffer: The data buffer of the STUN message + * @buffer_len: The length of @buffer + * @validater: A #StunMessageIntegrityValidate function callback that will + * be called if the agent needs to validate a MESSAGE-INTEGRITY attribute. It + * will only be called if the agent finds a message that needs authentication + * and a USERNAME is present in the STUN message, but no password is known. + * The validater will not be called if the #STUN_AGENT_USAGE_IGNORE_CREDENTIALS + * usage flag is set on the agent, and it will always be called if the + * #STUN_AGENT_USAGE_FORCE_VALIDATER usage flag is set on the agent. + * @validater_data: A user data to give to the @validater callback when it gets + * called. + * + * This function is used to validate an inbound STUN message and transform its + * data buffer into a #StunMessage. It will take care of various validation + * algorithms to make sure that the STUN message is valid and correctly + * authenticated. + * See also: stun_agent_default_validater() + * Returns: A #StunValidationStatus + + + if the return value is different from #STUN_VALIDATION_NOT_STUN or + #STUN_VALIDATION_INCOMPLETE_STUN, then the @msg argument will contain a valid + STUN message that can be used. + This means that you can use the @msg variable as the @request argument to + functions like stun_agent_init_error() or + stun_agent_build_unknown_attributes_error(). + If the return value is #STUN_VALIDATION_BAD_REQUEST, + #STUN_VALIDATION_UNAUTHORIZED or #STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST + then the @key in the #StunMessage will not be set, so that error responses + will not have a MESSAGE-INTEGRITY attribute. + + + */ +StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg, + const uint8_t *buffer, size_t buffer_len, + StunMessageIntegrityValidate validater, void * validater_data); + +/** + * stun_agent_init_request: + * @agent: The #StunAgent + * @msg: The #StunMessage to build + * @buffer: The buffer to use in the #StunMessage + * @buffer_len: The length of the buffer + * @m: The #StunMethod of the request + * + * Creates a new STUN message of class #STUN_REQUEST and with the method @m + * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise + */ +bool stun_agent_init_request (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, StunMethod m); + +/** + * stun_agent_init_indication: + * @agent: The #StunAgent + * @msg: The #StunMessage to build + * @buffer: The buffer to use in the #StunMessage + * @buffer_len: The length of the buffer + * @m: The #StunMethod of the indication + * + * Creates a new STUN message of class #STUN_INDICATION and with the method @m + * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise + */ +bool stun_agent_init_indication (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, StunMethod m); + +/** + * stun_agent_init_response: + * @agent: The #StunAgent + * @msg: The #StunMessage to build + * @buffer: The buffer to use in the #StunMessage + * @buffer_len: The length of the buffer + * @request: The #StunMessage of class #STUN_REQUEST that this response is for + * + * Creates a new STUN message of class #STUN_RESPONSE and with the same method + * and transaction ID as the message @request. This will also copy the pointer + * to the key that was used to authenticate the request, so you won't need to + * specify the key with stun_agent_finish_message() + * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise + */ +bool stun_agent_init_response (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, const StunMessage *request); + +/** + * stun_agent_init_error: + * @agent: The #StunAgent + * @msg: The #StunMessage to build + * @buffer: The buffer to use in the #StunMessage + * @buffer_len: The length of the buffer + * @request: The #StunMessage of class #STUN_REQUEST that this error response + * is for + * @err: The #StunError to put in the ERROR-CODE attribute of the error response + * + * Creates a new STUN message of class #STUN_ERROR and with the same method + * and transaction ID as the message @request. This will also copy the pointer + * to the key that was used to authenticate the request (if authenticated), + * so you won't need to specify the key with stun_agent_finish_message(). + * It will then add the ERROR-CODE attribute with code @err and the associated + * string. + * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise + */ +bool stun_agent_init_error (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, const StunMessage *request, + StunError err); + +/** + * stun_agent_build_unknown_attributes_error: + * @agent: The #StunAgent + * @msg: The #StunMessage to build + * @buffer: The buffer to use in the #StunMessage + * @buffer_len: The length of the buffer + * @request: The #StunMessage of class #STUN_REQUEST that this response is for + * + * Creates a new STUN message of class #STUN_ERROR and with the same method + * and transaction ID as the message @request. It will then add the ERROR-CODE + * attribute with code #STUN_ERROR_UNKNOWN_ATTRIBUTE and add all the unknown + * mandatory attributes from the @request STUN message in the + * #STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES attribute, it will then finish the message + * by calling stun_agent_finish_message() + * Returns: The size of the message built + */ +size_t stun_agent_build_unknown_attributes_error (StunAgent *agent, + StunMessage *msg, uint8_t *buffer, size_t buffer_len, + const StunMessage *request); + + +/** + * stun_agent_finish_message: + * @agent: The #StunAgent + * @msg: The #StunMessage to finish + * @key: The key to use for the MESSAGE-INTEGRITY attribute + * @key_len: The length of the @key + * + * This function will 'finish' a message and make it ready to be sent. It will + * add the MESSAGE-INTEGRITY and FINGERPRINT attributes if necessary. If the + * STUN message has a #STUN_REQUEST class, it will save the transaction id of + * the message in the agent for future matching of the response. + * See also: stun_agent_forget_transaction() + * Returns: The final size of the message built or 0 if an error occured + * + + The return value must always be checked. a value of 0 means the either + the buffer's size is too small to contain the finishing attributes + (MESSAGE-INTEGRITY, FINGERPRINT), or that there is no more free slots + for saving the sent id in the agent's state. + + + Everytime stun_agent_finish_message() is called for a #STUN_REQUEST + message, you must make sure to call stun_agent_forget_transaction() in + case the response times out and is never received. This is to avoid + filling up the #StunAgent's sent ids state preventing any further + use of the stun_agent_finish_message() + + + */ +size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg, + const uint8_t *key, size_t key_len); + +/** + * stun_agent_forget_transaction: + * @agent: The #StunAgent + * @id: The #StunTransactionId of the transaction to forget + * + * This function is used to make the #StunAgent forget about a previously + * created transaction. + * + * This function should be called when a STUN request was previously + * created with stun_agent_finish_message() and for which no response was ever + * received (timed out). The #StunAgent keeps a list of the sent transactions + * in order to validate the responses received. If the response is never received + * this will allow the #StunAgent to forget about the timed out transaction and + * free its slot for future transactions. + * + * Since: 0.0.6 + * Returns: %TRUE if the transaction was found, %FALSE otherwise + */ +bool stun_agent_forget_transaction (StunAgent *agent, StunTransactionId id); + + +/** + * stun_agent_set_software: + * @agent: The #StunAgent + * @software: The value of the SOFTWARE attribute to add. + * + * This function will set the value of the SOFTWARE attribute to be added to + * STUN requests, responses and error responses. + * + * Calling this function will automatically enable the addition of the SOFTWARE + * attribute for RFC5389 and MSICE2 compatibility modes. + * + * + * + + The @software argument must be in UTF-8 encoding and only the first + 128 characters will be sent. + + + The value of the @software argument must stay valid throughout the life of + the StunAgent's life. Do not free its content. + + + * + * Since: 0.0.10 + * + */ +void stun_agent_set_software (StunAgent *agent, const char *software); + +#endif /* _STUN_AGENT_H */ diff --git a/linux_x86/include/stun/stunmessage.h b/linux_x86/include/stun/stunmessage.h new file mode 100644 index 0000000..0ac9977 --- /dev/null +++ b/linux_x86/include/stun/stunmessage.h @@ -0,0 +1,1017 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2008-2009 Nokia Corporation. All rights reserved. + * Contact: Rémi Denis-Courmont + * + * 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. + * Rémi Denis-Courmont, Nokia + * + * 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 _STUN_MESSAGE_H +#define _STUN_MESSAGE_H + + +/** + * SECTION:stunmessage + * @short_description: STUN messages parsing and formatting functions + * @include: stun/stunmessage.h + * @see_also: #StunAgent + * @stability: Stable + * + * The STUN Messages API allows you to create STUN messages easily as well as to + * parse existing messages. + * + */ + + +#ifdef _WIN32 +#include "win32_common.h" +#else +#include +#include +#endif + +#include + +#ifdef _WIN32 +#include +#include +#else +#include +#include +#endif + +#include "constants.h" + +typedef struct _StunMessage StunMessage; + +/** + * StunClass: + * @STUN_REQUEST: A STUN Request message + * @STUN_INDICATION: A STUN indication message + * @STUN_RESPONSE: A STUN Response message + * @STUN_ERROR: A STUN Error message + * + * This enum is used to represent the class of + * a STUN message, as defined in RFC5389 + */ + +/* Message classes */ +typedef enum +{ + STUN_REQUEST=0, + STUN_INDICATION=1, + STUN_RESPONSE=2, + STUN_ERROR=3 +} StunClass; + + +/** + * StunMethod: + * @STUN_BINDING: The Binding method as defined by the RFC5389 + * @STUN_SHARED_SECRET: The Shared-Secret method as defined by the RFC3489 + * @STUN_ALLOCATE: The Allocate method as defined by the TURN draft 12 + * @STUN_SET_ACTIVE_DST: The Set-Active-Destination method as defined by + * the TURN draft 4 + * @STUN_REFRESH: The Refresh method as defined by the TURN draft 12 + * @STUN_SEND: The Send method as defined by the TURN draft 00 + * @STUN_CONNECT: The Connect method as defined by the TURN draft 4 + * @STUN_OLD_SET_ACTIVE_DST: The older Set-Active-Destination method as + * defined by the TURN draft 0 + * @STUN_IND_SEND: The Send method used in indication messages as defined + * by the TURN draft 12 + * @STUN_IND_DATA: The Data method used in indication messages as defined + * by the TURN draft 12 + * @STUN_IND_CONNECT_STATUS: The Connect-Status method used in indication + * messages as defined by the TURN draft 4 + * @STUN_CREATEPERMISSION: The CreatePermission method as defined by + * the TURN draft 12 + * @STUN_CHANNELBIND: The ChannelBind method as defined by the TURN draft 12 + * + * This enum is used to represent the method of + * a STUN message, as defined by various RFCs + */ +/* Message methods */ +typedef enum +{ + STUN_BINDING=0x001, /* RFC5389 */ + STUN_SHARED_SECRET=0x002, /* old RFC3489 */ + STUN_ALLOCATE=0x003, /* TURN-12 */ + STUN_SET_ACTIVE_DST=0x004, /* TURN-04 */ + STUN_REFRESH=0x004, /* TURN-12 */ + STUN_SEND=0x004, /* TURN-00 */ + STUN_CONNECT=0x005, /* TURN-04 */ + STUN_OLD_SET_ACTIVE_DST=0x006, /* TURN-00 */ + STUN_IND_SEND=0x006, /* TURN-12 */ + STUN_IND_DATA=0x007, /* TURN-12 */ + STUN_IND_CONNECT_STATUS=0x008, /* TURN-04 */ + STUN_CREATEPERMISSION= 0x008, /* TURN-12 */ + STUN_CHANNELBIND= 0x009 /* TURN-12 */ +} StunMethod; + +/** + * StunAttribute: + * @STUN_ATTRIBUTE_MAPPED_ADDRESS: The MAPPED-ADDRESS attribute as defined + * by RFC5389 + * @STUN_ATTRIBUTE_RESPONSE_ADDRESS: The RESPONSE-ADDRESS attribute as defined + * by RFC3489 + * @STUN_ATTRIBUTE_CHANGE_REQUEST: The CHANGE-REQUEST attribute as defined by + * RFC3489 + * @STUN_ATTRIBUTE_SOURCE_ADDRESS: The SOURCE-ADDRESS attribute as defined by + * RFC3489 + * @STUN_ATTRIBUTE_CHANGED_ADDRESS: The CHANGED-ADDRESS attribute as defined + * by RFC3489 + * @STUN_ATTRIBUTE_USERNAME: The USERNAME attribute as defined by RFC5389 + * @STUN_ATTRIBUTE_PASSWORD: The PASSWORD attribute as defined by RFC3489 + * @STUN_ATTRIBUTE_MESSAGE_INTEGRITY: The MESSAGE-INTEGRITY attribute as defined + * by RFC5389 + * @STUN_ATTRIBUTE_ERROR_CODE: The ERROR-CODE attribute as defined by RFC5389 + * @STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES: The UNKNOWN-ATTRIBUTES attribute as + * defined by RFC5389 + * @STUN_ATTRIBUTE_REFLECTED_FROM: The REFLECTED-FROM attribute as defined + * by RFC3489 + * @STUN_ATTRIBUTE_CHANNEL_NUMBER: The CHANNEL-NUMBER attribute as defined by + * TURN draft 09 and 12 + * @STUN_ATTRIBUTE_LIFETIME: The LIFETIME attribute as defined by TURN + * draft 04, 09 and 12 + * @STUN_ATTRIBUTE_MS_ALTERNATE_SERVER: The ALTERNATE-SERVER attribute as + * defined by [MS-TURN] + * @STUN_ATTRIBUTE_MAGIC_COOKIE: The MAGIC-COOKIE attribute as defined by + * the rosenberg-midcom TURN draft 08 + * @STUN_ATTRIBUTE_BANDWIDTH: The BANDWIDTH attribute as defined by TURN draft 04 + * @STUN_ATTRIBUTE_DESTINATION_ADDRESS: The DESTINATION-ADDRESS attribute as + * defined by the rosenberg-midcom TURN draft 08 + * @STUN_ATTRIBUTE_REMOTE_ADDRESS: The REMOTE-ADDRESS attribute as defined by + * TURN draft 04 + * @STUN_ATTRIBUTE_PEER_ADDRESS: The PEER-ADDRESS attribute as defined by + * TURN draft 09 + * @STUN_ATTRIBUTE_XOR_PEER_ADDRESS: The XOR-PEER-ADDRESS attribute as defined + * by TURN draft 12 + * @STUN_ATTRIBUTE_DATA: The DATA attribute as defined by TURN draft 04, + * 09 and 12 + * @STUN_ATTRIBUTE_REALM: The REALM attribute as defined by RFC5389 + * @STUN_ATTRIBUTE_NONCE: The NONCE attribute as defined by RFC5389 + * @STUN_ATTRIBUTE_RELAY_ADDRESS: The RELAY-ADDRESS attribute as defined by + * TURN draft 04 + * @STUN_ATTRIBUTE_RELAYED_ADDRESS: The RELAYED-ADDRESS attribute as defined by + * TURN draft 09 + * @STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS: The XOR-RELAYED-ADDRESS attribute as + * defined by TURN draft 12 + * @STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE: The REQUESTED-ADDRESS-TYPE attribute + * as defined by TURN-IPV6 draft 05 + * @STUN_ATTRIBUTE_REQUESTED_PORT_PROPS: The REQUESTED-PORT-PROPS attribute + * as defined by TURN draft 04 + * @STUN_ATTRIBUTE_REQUESTED_PROPS: The REQUESTED-PROPS attribute as defined + * by TURN draft 09 + * @STUN_ATTRIBUTE_EVEN_PORT: The EVEN-PORT attribute as defined by TURN draft 12 + * @STUN_ATTRIBUTE_REQUESTED_TRANSPORT: The REQUESTED-TRANSPORT attribute as + * defined by TURN draft 12 + * @STUN_ATTRIBUTE_DONT_FRAGMENT: The DONT-FRAGMENT attribute as defined + * by TURN draft 12 + * @STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS: The XOR-MAPPED-ADDRESS attribute as + * defined by RFC5389 + * @STUN_ATTRIBUTE_TIMER_VAL: The TIMER-VAL attribute as defined by TURN draft 04 + * @STUN_ATTRIBUTE_REQUESTED_IP: The REQUESTED-IP attribute as defined by + * TURN draft 04 + * @STUN_ATTRIBUTE_RESERVATION_TOKEN: The RESERVATION-TOKEN attribute as defined + * by TURN draft 09 and 12 + * @STUN_ATTRIBUTE_CONNECT_STAT: The CONNECT-STAT attribute as defined by TURN + * draft 04 + * @STUN_ATTRIBUTE_PRIORITY: The PRIORITY attribute as defined by ICE draft 19 + * @STUN_ATTRIBUTE_USE_CANDIDATE: The USE-CANDIDATE attribute as defined by + * ICE draft 19 + * @STUN_ATTRIBUTE_OPTIONS: The OPTIONS optional attribute as defined by + * libjingle + * @STUN_ATTRIBUTE_MS_VERSION: The MS-VERSION optional attribute as defined + * by [MS-TURN] + * @STUN_ATTRIBUTE_MS_XOR_MAPPED_ADDRESS: The XOR-MAPPED-ADDRESS optional + * attribute as defined by [MS-TURN] + * @STUN_ATTRIBUTE_SOFTWARE: The SOFTWARE optional attribute as defined by RFC5389 + * @STUN_ATTRIBUTE_ALTERNATE_SERVER: The ALTERNATE-SERVER optional attribute as + * defined by RFC5389 + * @STUN_ATTRIBUTE_FINGERPRINT: The FINGERPRINT optional attribute as defined + * by RFC5389 + * @STUN_ATTRIBUTE_ICE_CONTROLLED: The ICE-CONTROLLED optional attribute as + * defined by ICE draft 19 + * @STUN_ATTRIBUTE_ICE_CONTROLLING: The ICE-CONTROLLING optional attribute as + * defined by ICE draft 19 + * @STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER: The MS-SEQUENCE NUMBER optional attribute + * as defined by [MS-TURN] + * @STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER: The CANDIDATE-IDENTIFIER optional + * attribute as defined by [MS-ICE2] + * @STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION: The IMPLEMENTATION-VERSION + * optional attribute as defined by [MS-ICE2] + * @STUN_ATTRIBUTE_NOMINATION: The NOMINATION attribute as defined by + * draft-thatcher-ice-renomination-00 and deployed in Google Chrome + * + * Known STUN attribute types as defined by various RFCs and drafts + */ +/* Should be in sync with stun_is_unknown() */ +typedef enum +{ + /* Mandatory attributes */ + /* 0x0000 */ /* reserved */ + STUN_ATTRIBUTE_MAPPED_ADDRESS=0x0001, /* RFC5389 */ + STUN_ATTRIBUTE_RESPONSE_ADDRESS=0x0002, /* old RFC3489 */ + STUN_ATTRIBUTE_CHANGE_REQUEST=0x0003, /* old RFC3489 */ + STUN_ATTRIBUTE_SOURCE_ADDRESS=0x0004, /* old RFC3489 */ + STUN_ATTRIBUTE_CHANGED_ADDRESS=0x0005, /* old RFC3489 */ + STUN_ATTRIBUTE_USERNAME=0x0006, /* RFC5389 */ + STUN_ATTRIBUTE_PASSWORD=0x0007, /* old RFC3489 */ + STUN_ATTRIBUTE_MESSAGE_INTEGRITY=0x0008, /* RFC5389 */ + STUN_ATTRIBUTE_ERROR_CODE=0x0009, /* RFC5389 */ + STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES=0x000A, /* RFC5389 */ + STUN_ATTRIBUTE_REFLECTED_FROM=0x000B, /* old RFC3489 */ + STUN_ATTRIBUTE_CHANNEL_NUMBER=0x000C, /* TURN-12 */ + STUN_ATTRIBUTE_LIFETIME=0x000D, /* TURN-12 */ + /* MS_ALTERNATE_SERVER is only used by Microsoft's dialect, probably should + * not to be placed in STUN_ALL_KNOWN_ATTRIBUTES */ + STUN_ATTRIBUTE_MS_ALTERNATE_SERVER=0x000E, /* MS-TURN */ + STUN_ATTRIBUTE_MAGIC_COOKIE=0x000F, /* midcom-TURN 08 */ + STUN_ATTRIBUTE_BANDWIDTH=0x0010, /* TURN-04 */ + STUN_ATTRIBUTE_DESTINATION_ADDRESS=0x0011, /* midcom-TURN 08 */ + STUN_ATTRIBUTE_REMOTE_ADDRESS=0x0012, /* TURN-04 */ + STUN_ATTRIBUTE_PEER_ADDRESS=0x0012, /* TURN-09 */ + STUN_ATTRIBUTE_XOR_PEER_ADDRESS=0x0012, /* TURN-12 */ + STUN_ATTRIBUTE_DATA=0x0013, /* TURN-12 */ + STUN_ATTRIBUTE_REALM=0x0014, /* RFC5389 */ + STUN_ATTRIBUTE_NONCE=0x0015, /* RFC5389 */ + STUN_ATTRIBUTE_RELAY_ADDRESS=0x0016, /* TURN-04 */ + STUN_ATTRIBUTE_RELAYED_ADDRESS=0x0016, /* TURN-09 */ + STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS=0x0016, /* TURN-12 */ + STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE=0x0017, /* TURN-IPv6-05 */ + STUN_ATTRIBUTE_REQUESTED_PORT_PROPS=0x0018, /* TURN-04 */ + STUN_ATTRIBUTE_REQUESTED_PROPS=0x0018, /* TURN-09 */ + STUN_ATTRIBUTE_EVEN_PORT=0x0018, /* TURN-12 */ + STUN_ATTRIBUTE_REQUESTED_TRANSPORT=0x0019, /* TURN-12 */ + STUN_ATTRIBUTE_DONT_FRAGMENT=0x001A, /* TURN-12 */ + /* 0x001B */ /* reserved */ + /* 0x001C */ /* reserved */ + /* 0x001D */ /* reserved */ + /* 0x001E */ /* reserved */ + /* 0x001F */ /* reserved */ + STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS=0x0020, /* RFC5389 */ + STUN_ATTRIBUTE_TIMER_VAL=0x0021, /* TURN-04 */ + STUN_ATTRIBUTE_REQUESTED_IP=0x0022, /* TURN-04 */ + STUN_ATTRIBUTE_RESERVATION_TOKEN=0x0022, /* TURN-09 */ + STUN_ATTRIBUTE_CONNECT_STAT=0x0023, /* TURN-04 */ + STUN_ATTRIBUTE_PRIORITY=0x0024, /* ICE-19 */ + STUN_ATTRIBUTE_USE_CANDIDATE=0x0025, /* ICE-19 */ + /* 0x0026 */ /* reserved */ + /* 0x0027 */ /* reserved */ + /* 0x0028 */ /* reserved */ + /* 0x0029 */ /* reserved */ + /* 0x002A-0x7fff */ /* reserved */ + + /* Optional attributes */ + /* 0x8000-0x8021 */ /* reserved */ + STUN_ATTRIBUTE_OPTIONS=0x8001, /* libjingle */ + STUN_ATTRIBUTE_MS_VERSION=0x8008, /* MS-TURN */ + STUN_ATTRIBUTE_MS_XOR_MAPPED_ADDRESS=0x8020, /* MS-TURN */ + STUN_ATTRIBUTE_SOFTWARE=0x8022, /* RFC5389 */ + STUN_ATTRIBUTE_ALTERNATE_SERVER=0x8023, /* RFC5389 */ + /* 0x8024 */ /* reserved */ + /* 0x8025 */ /* reserved */ + /* 0x8026 */ /* reserved */ + /* 0x8027 */ /* reserved */ + STUN_ATTRIBUTE_FINGERPRINT=0x8028, /* RFC5389 */ + STUN_ATTRIBUTE_ICE_CONTROLLED=0x8029, /* ICE-19 */ + STUN_ATTRIBUTE_ICE_CONTROLLING=0x802A, /* ICE-19 */ + /* 0x802B-0x804F */ /* reserved */ + STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER=0x8050, /* MS-TURN */ + /* 0x8051-0x8053 */ /* reserved */ + STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER=0x8054, /* MS-ICE2 */ + /* 0x8055-0x806F */ /* reserved */ + STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION=0x8070, /* MS-ICE2 */ + /* 0x8071-0xC000 */ /* reserved */ + STUN_ATTRIBUTE_NOMINATION=0xC001 /* https://tools.ietf.org/html/draft-thatcher-ice-renomination-00 */ + /* 0xC002-0xFFFF */ /* reserved */ +} StunAttribute; + + +/** + * STUN_ALL_KNOWN_ATTRIBUTES: + * + * An array containing all the currently known and defined mandatory attributes + * from StunAttribute + */ +/* Should be in sync with StunAttribute */ +static const uint16_t STUN_ALL_KNOWN_ATTRIBUTES[] = + { + STUN_ATTRIBUTE_MAPPED_ADDRESS, + STUN_ATTRIBUTE_RESPONSE_ADDRESS, + STUN_ATTRIBUTE_CHANGE_REQUEST, + STUN_ATTRIBUTE_SOURCE_ADDRESS, + STUN_ATTRIBUTE_CHANGED_ADDRESS, + STUN_ATTRIBUTE_USERNAME, + STUN_ATTRIBUTE_PASSWORD, + STUN_ATTRIBUTE_MESSAGE_INTEGRITY, + STUN_ATTRIBUTE_ERROR_CODE, + STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, + STUN_ATTRIBUTE_REFLECTED_FROM, + STUN_ATTRIBUTE_CHANNEL_NUMBER, + STUN_ATTRIBUTE_LIFETIME, + STUN_ATTRIBUTE_MAGIC_COOKIE, + STUN_ATTRIBUTE_BANDWIDTH, + STUN_ATTRIBUTE_DESTINATION_ADDRESS, + STUN_ATTRIBUTE_REMOTE_ADDRESS, + STUN_ATTRIBUTE_PEER_ADDRESS, + STUN_ATTRIBUTE_XOR_PEER_ADDRESS, + STUN_ATTRIBUTE_DATA, + STUN_ATTRIBUTE_REALM, + STUN_ATTRIBUTE_NONCE, + STUN_ATTRIBUTE_RELAY_ADDRESS, + STUN_ATTRIBUTE_RELAYED_ADDRESS, + STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, + STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE, + STUN_ATTRIBUTE_REQUESTED_PORT_PROPS, + STUN_ATTRIBUTE_REQUESTED_PROPS, + STUN_ATTRIBUTE_EVEN_PORT, + STUN_ATTRIBUTE_REQUESTED_TRANSPORT, + STUN_ATTRIBUTE_DONT_FRAGMENT, + STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, + STUN_ATTRIBUTE_TIMER_VAL, + STUN_ATTRIBUTE_REQUESTED_IP, + STUN_ATTRIBUTE_RESERVATION_TOKEN, + STUN_ATTRIBUTE_CONNECT_STAT, + STUN_ATTRIBUTE_PRIORITY, + STUN_ATTRIBUTE_USE_CANDIDATE, + 0 + }; + +/** + * STUN_MSOC_KNOWN_ATTRIBUTES: + * + * An array containing all the currently known mandatory attributes used by + * Microsoft Office Communicator as defined in [MS-TURN] + */ +static const uint16_t STUN_MSOC_KNOWN_ATTRIBUTES[] = + { + STUN_ATTRIBUTE_MAPPED_ADDRESS, + STUN_ATTRIBUTE_USERNAME, + STUN_ATTRIBUTE_MESSAGE_INTEGRITY, + STUN_ATTRIBUTE_ERROR_CODE, + STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, + STUN_ATTRIBUTE_LIFETIME, + STUN_ATTRIBUTE_MS_ALTERNATE_SERVER, + STUN_ATTRIBUTE_MAGIC_COOKIE, + STUN_ATTRIBUTE_BANDWIDTH, + STUN_ATTRIBUTE_DESTINATION_ADDRESS, + STUN_ATTRIBUTE_REMOTE_ADDRESS, + STUN_ATTRIBUTE_DATA, + /* REALM and NONCE have swapped hexadecimal IDs in [MS-TURN]. Libnice users + * or developers can still use these enumeration values in their original + * meanings from StunAttribute anywhere in the code, as stun_message_find() + * and stun_message_append() will choose correct ID in MSOC compatibility + * modes. */ + STUN_ATTRIBUTE_NONCE, + STUN_ATTRIBUTE_REALM, + 0 + }; + +/** + * StunTransactionId: + * + * A type that holds a STUN transaction id. + */ +typedef uint8_t StunTransactionId[STUN_MESSAGE_TRANS_ID_LEN]; + + +/** + * StunError: + * @STUN_ERROR_TRY_ALTERNATE: The ERROR-CODE value for the + * "Try Alternate" error as defined in RFC5389 + * @STUN_ERROR_BAD_REQUEST: The ERROR-CODE value for the + * "Bad Request" error as defined in RFC5389 + * @STUN_ERROR_UNAUTHORIZED: The ERROR-CODE value for the + * "Unauthorized" error as defined in RFC5389 + * @STUN_ERROR_UNKNOWN_ATTRIBUTE: The ERROR-CODE value for the + * "Unknown Attribute" error as defined in RFC5389 + * @STUN_ERROR_ALLOCATION_MISMATCH:The ERROR-CODE value for the + * "Allocation Mismatch" error as defined in TURN draft 12. + * Equivalent to the "No Binding" error defined in TURN draft 04. + * @STUN_ERROR_STALE_NONCE: The ERROR-CODE value for the + * "Stale Nonce" error as defined in RFC5389 + * @STUN_ERROR_ACT_DST_ALREADY: The ERROR-CODE value for the + * "Active Destination Already Set" error as defined in TURN draft 04. + * @STUN_ERROR_UNSUPPORTED_FAMILY: The ERROR-CODE value for the + * "Address Family not Supported" error as defined in TURN IPV6 Draft 05. + * @STUN_ERROR_WRONG_CREDENTIALS: The ERROR-CODE value for the + * "Wrong Credentials" error as defined in TURN Draft 12. + * @STUN_ERROR_UNSUPPORTED_TRANSPORT:he ERROR-CODE value for the + * "Unsupported Transport Protocol" error as defined in TURN Draft 12. + * @STUN_ERROR_INVALID_IP: The ERROR-CODE value for the + * "Invalid IP Address" error as defined in TURN draft 04. + * @STUN_ERROR_INVALID_PORT: The ERROR-CODE value for the + * "Invalid Port" error as defined in TURN draft 04. + * @STUN_ERROR_OP_TCP_ONLY: The ERROR-CODE value for the + * "Operation for TCP Only" error as defined in TURN draft 04. + * @STUN_ERROR_CONN_ALREADY: The ERROR-CODE value for the + * "Connection Already Exists" error as defined in TURN draft 04. + * @STUN_ERROR_ALLOCATION_QUOTA_REACHED: The ERROR-CODE value for the + * "Allocation Quota Reached" error as defined in TURN draft 12. + * @STUN_ERROR_ROLE_CONFLICT:The ERROR-CODE value for the + * "Role Conflict" error as defined in ICE draft 19. + * @STUN_ERROR_SERVER_ERROR: The ERROR-CODE value for the + * "Server Error" error as defined in RFC5389 + * @STUN_ERROR_SERVER_CAPACITY: The ERROR-CODE value for the + * "Insufficient Capacity" error as defined in TURN draft 04. + * @STUN_ERROR_INSUFFICIENT_CAPACITY: The ERROR-CODE value for the + * "Insufficient Capacity" error as defined in TURN draft 12. + * @STUN_ERROR_MAX: The maximum possible ERROR-CODE value as defined by RFC 5389. + * + * STUN error codes as defined by various RFCs and drafts + */ +/* Should be in sync with stun_strerror() */ +typedef enum +{ + STUN_ERROR_TRY_ALTERNATE=300, /* RFC5389 */ + STUN_ERROR_BAD_REQUEST=400, /* RFC5389 */ + STUN_ERROR_UNAUTHORIZED=401, /* RFC5389 */ + STUN_ERROR_UNKNOWN_ATTRIBUTE=420, /* RFC5389 */ + STUN_ERROR_ALLOCATION_MISMATCH=437, /* TURN-12 */ + STUN_ERROR_STALE_NONCE=438, /* RFC5389 */ + STUN_ERROR_ACT_DST_ALREADY=439, /* TURN-04 */ + STUN_ERROR_UNSUPPORTED_FAMILY=440, /* TURN-IPv6-05 */ + STUN_ERROR_WRONG_CREDENTIALS=441, /* TURN-12 */ + STUN_ERROR_UNSUPPORTED_TRANSPORT=442, /* TURN-12 */ + STUN_ERROR_INVALID_IP=443, /* TURN-04 */ + STUN_ERROR_INVALID_PORT=444, /* TURN-04 */ + STUN_ERROR_OP_TCP_ONLY=445, /* TURN-04 */ + STUN_ERROR_CONN_ALREADY=446, /* TURN-04 */ + STUN_ERROR_ALLOCATION_QUOTA_REACHED=486, /* TURN-12 */ + STUN_ERROR_ROLE_CONFLICT=487, /* ICE-19 */ + STUN_ERROR_SERVER_ERROR=500, /* RFC5389 */ + STUN_ERROR_SERVER_CAPACITY=507, /* TURN-04 */ + STUN_ERROR_INSUFFICIENT_CAPACITY=508, /* TURN-12 */ + STUN_ERROR_MAX=699 +} StunError; + + +/** + * StunMessageReturn: + * @STUN_MESSAGE_RETURN_SUCCESS: The operation was successful + * @STUN_MESSAGE_RETURN_NOT_FOUND: The attribute was not found + * @STUN_MESSAGE_RETURN_INVALID: The argument or data is invalid + * @STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE: There is not enough space in the + * message to append data to it, or not enough in an argument to fill it with + * the data requested. + * @STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS: The address in the arguments or in + * the STUN message is not supported. + * + * The return value of most stun_message_* functions. + * This enum will report on whether an operation was successful or not + * and what error occured if any. + */ +typedef enum +{ + STUN_MESSAGE_RETURN_SUCCESS, + STUN_MESSAGE_RETURN_NOT_FOUND, + STUN_MESSAGE_RETURN_INVALID, + STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE, + STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS +} StunMessageReturn; + +#include "stunagent.h" + +/** + * STUN_MAX_MESSAGE_SIZE: + * + * The Maximum size of a STUN message + */ +#define STUN_MAX_MESSAGE_SIZE 65552 + +/** + * StunMessage: + * @agent: The agent that created or validated this message + * @buffer: The buffer containing the STUN message + * @buffer_len: The length of the buffer (not the size of the message) + * @key: The short term credentials key to use for authentication validation + * or that was used to finalize this message + * @key_len: The length of the associated key + * @long_term_key: The long term credential key to use for authentication + * validation or that was used to finalize this message + * @long_term_valid: Whether or not the #long_term_key variable contains valid + * data + * + * This structure represents a STUN message + */ +struct _StunMessage { + StunAgent *agent; + uint8_t *buffer; + size_t buffer_len; + uint8_t *key; + size_t key_len; + uint8_t long_term_key[16]; + bool long_term_valid; +}; + +/** + * stun_message_init: + * @msg: The #StunMessage to initialize + * @c: STUN message class (host byte order) + * @m: STUN message method (host byte order) + * @id: 16-bytes transaction ID + * + * Initializes a STUN message buffer, with no attributes. + * Returns: %TRUE if the initialization was successful + */ +bool stun_message_init (StunMessage *msg, StunClass c, StunMethod m, + const StunTransactionId id); + +/** + * stun_message_length: + * @msg: The #StunMessage + * + * Get the length of the message (including the header) + * + * Returns: The length of the message + */ +uint16_t stun_message_length (const StunMessage *msg); + +/** + * stun_message_find: + * @msg: The #StunMessage + * @type: The #StunAttribute to find + * @palen: A pointer to store the length of the attribute + * + * Finds an attribute in a STUN message and fetches its content + * + * Returns: A pointer to the start of the attribute payload if found, + * otherwise NULL. + */ +const void * stun_message_find (const StunMessage * msg, StunAttribute type, + uint16_t *palen); + + +/** + * stun_message_find_flag: + * @msg: The #StunMessage + * @type: The #StunAttribute to find + * + * Looks for a flag attribute within a valid STUN message. + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not zero. + */ +StunMessageReturn stun_message_find_flag (const StunMessage *msg, + StunAttribute type); + +/** + * stun_message_find32: + * @msg: The #StunMessage + * @type: The #StunAttribute to find + * @pval: A pointer where to store the value (host byte order) + * + * Extracts a 32-bits attribute from a STUN message. + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not + * 4 bytes. + */ +StunMessageReturn stun_message_find32 (const StunMessage *msg, + StunAttribute type, uint32_t *pval); + +/** + * stun_message_find64: + * @msg: The #StunMessage + * @type: The #StunAttribute to find + * @pval: A pointer where to store the value (host byte order) + * + * Extracts a 64-bits attribute from a STUN message. + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not + * 8 bytes. + */ +StunMessageReturn stun_message_find64 (const StunMessage *msg, + StunAttribute type, uint64_t *pval); + +/** + * stun_message_find_string: + * @msg: The #StunMessage + * @type: The #StunAttribute to find + * @buf: A pointer where to store the data + * @buflen: The length of the buffer + * + * Extracts an UTF-8 string from a valid STUN message. + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute is improperly + * encoded + * %STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE is return if the buffer size is too + * small to hold the string + * + + + The string will be nul-terminated. + + + * + */ +StunMessageReturn stun_message_find_string (const StunMessage *msg, + StunAttribute type, char *buf, size_t buflen); + +/** + * stun_message_find_addr: + * @msg: The #StunMessage + * @type: The #StunAttribute to find + * @addr: The #sockaddr to be filled + * @addrlen: The size of the @addr variable. Must be set to the size of the + * @addr socket address and will be set to the size of the extracted socket + * address. + * + * Extracts a network address attribute from a STUN message. + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is + * wrong or if the @addrlen is too small + * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. + */ +StunMessageReturn stun_message_find_addr (const StunMessage *msg, + StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen); + +/** + * stun_message_find_xor_addr: + * @msg: The #StunMessage + * @type: The #StunAttribute to find + * @addr: The #sockaddr to be filled + * @addrlen: The size of the @addr variable. Must be set to the size of the + * @addr socket address and will be set to the size of the + * extracted socket address. + * + * Extracts an obfuscated network address attribute from a STUN message. + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is + * wrong or if the @addrlen is too small + * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. + */ +StunMessageReturn stun_message_find_xor_addr (const StunMessage *msg, + StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen); + +/** + * stun_message_find_xor_addr_full: + * @msg: The #StunMessage + * @type: The #StunAttribute to find + * @addr: The #sockaddr to be filled + * @addrlen: The size of the @addr variable. Must be set to the size of the + * @addr socket address and will be set to the size of the + * extracted socket address. + * @magic_cookie: The magic cookie to use to XOR the address. + * + * Extracts an obfuscated network address attribute from a STUN message. + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is + * wrong or if the @addrlen is too small + * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. + */ +StunMessageReturn stun_message_find_xor_addr_full (const StunMessage *msg, + StunAttribute type, struct sockaddr_storage *addr, + socklen_t *addrlen, uint32_t magic_cookie); + + +/** + * stun_message_find_error: + * @msg: The #StunMessage + * @code: A pointer where to store the value + * + * Extract the error response code from a STUN message + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the value is invalid + */ +StunMessageReturn stun_message_find_error (const StunMessage *msg, int *code); + + +/** + * stun_message_append: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * @length: The length of the attribute + * + * Reserves room for appending an attribute to an unfinished STUN message. + * + * Returns: A pointer to an unitialized buffer of @length bytes to + * where the attribute payload must be written, or NULL if there is not + * enough room in the STUN message buffer. + */ +void *stun_message_append (StunMessage *msg, StunAttribute type, + size_t length); + +/** + * stun_message_append_bytes: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * @data: The data to append + * @len: The length of the attribute + * + * Appends a binary value to a STUN message + * + * Returns: A #StunMessageReturn value. + */ +StunMessageReturn stun_message_append_bytes (StunMessage *msg, + StunAttribute type, const void *data, size_t len); + +/** + * stun_message_append_flag: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * + * Appends an empty flag attribute to a STUN message + * + * Returns: A #StunMessageReturn value. + */ +StunMessageReturn stun_message_append_flag (StunMessage *msg, + StunAttribute type); + +/** + * stun_message_append32: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * @value: The value to append (host byte order) + * + * Appends a 32-bits value attribute to a STUN message + * + * Returns: A #StunMessageReturn value. + */ +StunMessageReturn stun_message_append32 (StunMessage *msg, + StunAttribute type, uint32_t value); + +/** + * stun_message_append64: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * @value: The value to append (host byte order) + * + * Appends a 64-bits value attribute to a STUN message + * + * Returns: A #StunMessageReturn value. + */ +StunMessageReturn stun_message_append64 (StunMessage *msg, + StunAttribute type, uint64_t value); + +/** + * stun_message_append_string: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * @str: The string to append + * + * Adds an attribute from a nul-terminated string to a STUN message + * + * Returns: A #StunMessageReturn value. + */ +StunMessageReturn stun_message_append_string (StunMessage *msg, + StunAttribute type, const char *str); + +/** + * stun_message_append_addr: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * @addr: The #sockaddr to be append + * @addrlen: The size of the @addr variable. + * + * Append a network address attribute to a STUN message + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small + * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. + */ +StunMessageReturn stun_message_append_addr (StunMessage * msg, + StunAttribute type, const struct sockaddr *addr, socklen_t addrlen); + +/** + * stun_message_append_xor_addr: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * @addr: The #sockaddr to be append + * @addrlen: The size of the @addr variable. + * + * Append an obfuscated network address attribute to a STUN message + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small + * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. + */ +StunMessageReturn stun_message_append_xor_addr (StunMessage * msg, + StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen); + +/** + * stun_message_append_xor_addr_full: + * @msg: The #StunMessage + * @type: The #StunAttribute to append + * @addr: The #sockaddr to be append + * @addrlen: The size of the @addr variable. + * @magic_cookie: The magic cookie to use to XOR the address. + * + * Append an obfuscated network address attribute from a STUN message. + * + * Returns: A #StunMessageReturn value. + * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small + * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. + */ +StunMessageReturn stun_message_append_xor_addr_full (StunMessage * msg, + StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen, + uint32_t magic_cookie); + +/** + * stun_message_append_error: + * @msg: The #StunMessage + * @code: The error code value + * + * Appends the ERROR-CODE attribute to the STUN message and fills it according + * to #code + * + * Returns: A #StunMessageReturn value. + */ +StunMessageReturn stun_message_append_error (StunMessage * msg, + StunError code); + +/** + * STUN_MESSAGE_BUFFER_INCOMPLETE: + * + * Convenience macro for stun_message_validate_buffer_length() meaning that the + * data to validate does not hold a complete STUN message + */ +#define STUN_MESSAGE_BUFFER_INCOMPLETE 0 + +/** + * STUN_MESSAGE_BUFFER_INVALID: + * + * Convenience macro for stun_message_validate_buffer_length() meaning that the + * data to validate is not a valid STUN message + */ +#define STUN_MESSAGE_BUFFER_INVALID -1 + + +/** + * stun_message_validate_buffer_length: + * @msg: The buffer to validate + * @length: The length of the buffer + * @has_padding: Set TRUE if attributes should be padded to multiple of 4 bytes + * + * This function will take a data buffer and will try to validate whether it is + * a STUN message or if it's not or if it's an incomplete STUN message and will + * provide us with the length of the STUN message. + * + * Returns: The length of the valid STUN message in the buffer. + * See also: #STUN_MESSAGE_BUFFER_INCOMPLETE + * See also: #STUN_MESSAGE_BUFFER_INVALID + */ +int stun_message_validate_buffer_length (const uint8_t *msg, size_t length, + bool has_padding); + +/** + * StunInputVector: + * @buffer: a buffer containing already-received binary data + * @size: length of @buffer, in bytes + * + * Container for a single buffer which also stores its length. This is designed + * for vectored I/O: typically an array of #StunInputVectors is passed to + * functions, providing multiple buffers which store logically contiguous + * received data. + * + * This is guaranteed to be layed out identically in memory to #GInputVector. + * + * Since: 0.1.5 + */ +typedef struct { + const uint8_t *buffer; + size_t size; +} StunInputVector; + +/** + * stun_message_validate_buffer_length_fast: + * @buffers: (array length=n_buffers) (in caller-allocated): array of contiguous + * #StunInputVectors containing already-received message data + * @n_buffers: number of entries in @buffers or if -1 , then buffers is + * terminated by a #StunInputVector with the buffer pointer being %NULL. + * @total_length: total number of valid bytes stored consecutively in @buffers + * @has_padding: %TRUE if attributes should be padded to 4-byte boundaries + * + * Quickly validate whether the message in the given @buffers is potentially a + * valid STUN message, an incomplete STUN message, or if it’s definitely not one + * at all. + * + * This is designed as a first-pass validation only, and does not check the + * message’s attributes for validity. If this function returns success, the + * buffers can be compacted and a more thorough validation can be performed + * using stun_message_validate_buffer_length(). If it fails, the buffers + * definitely do not contain a complete, valid STUN message. + * + * Returns: The length of the valid STUN message in the buffer, or zero or -1 on + * failure + * See also: #STUN_MESSAGE_BUFFER_INCOMPLETE + * See also: #STUN_MESSAGE_BUFFER_INVALID + * + * Since: 0.1.5 + */ +ssize_t stun_message_validate_buffer_length_fast (StunInputVector *buffers, + int n_buffers, size_t total_length, bool has_padding); + +/** + * stun_message_id: + * @msg: The #StunMessage + * @id: The #StunTransactionId to fill + * + * Retreive the STUN transaction id from a STUN message + */ +void stun_message_id (const StunMessage *msg, StunTransactionId id); + +/** + * stun_message_get_class: + * @msg: The #StunMessage + * + * Retreive the STUN class from a STUN message + * + * Returns: The #StunClass + */ +StunClass stun_message_get_class (const StunMessage *msg); + +/** + * stun_message_get_method: + * @msg: The #StunMessage + * + * Retreive the STUN method from a STUN message + * + * Returns: The #StunMethod + */ +StunMethod stun_message_get_method (const StunMessage *msg); + +/** + * stun_message_has_attribute: + * @msg: The #StunMessage + * @type: The #StunAttribute to look for + * + * Checks if an attribute is present within a STUN message. + * + * Returns: %TRUE if the attribute is found, %FALSE otherwise + */ +bool stun_message_has_attribute (const StunMessage *msg, StunAttribute type); + + +/* Defined in stun5389.c */ +/** + * stun_message_has_cookie: + * @msg: The #StunMessage + * + * Checks if the STUN message has a RFC5389 compatible cookie + * + * Returns: %TRUE if the cookie is present, %FALSE otherwise + */ +bool stun_message_has_cookie (const StunMessage *msg); + + +/** + * stun_optional: + * @t: An attribute type + * + * Helper function that checks whether a STUN attribute is a mandatory + * or an optional attribute + * + * Returns: %TRUE if the attribute is an optional one + */ +bool stun_optional (uint16_t t); + +/** + * stun_strerror: + * @code: host-byte order error code + * + * Transforms a STUN error-code into a human readable string + * + * Returns: A static pointer to a nul-terminated error message string. + */ +const char *stun_strerror (StunError code); + + +#endif /* _STUN_MESSAGE_H */ diff --git a/linux_x86/include/stun/usages/bind.h b/linux_x86/include/stun/usages/bind.h new file mode 100644 index 0000000..500f9fe --- /dev/null +++ b/linux_x86/include/stun/usages/bind.h @@ -0,0 +1,165 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2007-2009 Nokia Corporation. All rights reserved. + * Contact: Rémi Denis-Courmont + * + * 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. + * Rémi Denis-Courmont, Nokia + * + * 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 STUN_BIND_H +# define STUN_BIND_H 1 + +/** + * SECTION:bind + * @short_description: STUN Binding Usage + * @include: stun/usages/bind.h + * @stability: Stable + * + * The STUN Binding usage allows for easily creating and parsing STUN Binding + * requests and responses. It offers both an asynchronous and a synchronous API + * that uses the STUN timer usage. + */ + + +#ifdef _WIN32 +# include "../win32_common.h" +#else +# include +# include +#endif + +# include "stun/stunagent.h" + +# ifdef __cplusplus +extern "C" { +# endif + +/** + * StunUsageBindReturn: + * @STUN_USAGE_BIND_RETURN_SUCCESS: The binding usage succeeded + * @STUN_USAGE_BIND_RETURN_ERROR: There was an unknown error in the bind usage + * @STUN_USAGE_BIND_RETURN_INVALID: The message is invalid and should be ignored + * @STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER: The binding request has an + * ALTERNATE-SERVER attribute + * @STUN_USAGE_BIND_RETURN_TIMEOUT: The binding was unsuccessful because it has + * timed out. + * + * Return value of stun_usage_bind_process() and stun_usage_bind_run() which + * allows you to see what status the function call returned. + */ +typedef enum { + STUN_USAGE_BIND_RETURN_SUCCESS, + STUN_USAGE_BIND_RETURN_ERROR, + STUN_USAGE_BIND_RETURN_INVALID, + STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER, + STUN_USAGE_BIND_RETURN_TIMEOUT, +} StunUsageBindReturn; + + +/** + * stun_usage_bind_create: + * @agent: The #StunAgent to use to create the binding request + * @msg: The #StunMessage to build + * @buffer: The buffer to use for creating the #StunMessage + * @buffer_len: The size of the @buffer + * + * Create a new STUN binding request to use with a STUN server. + * Returns: The length of the built message. + */ +size_t stun_usage_bind_create (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len); + +/** + * stun_usage_bind_process: + * @msg: The #StunMessage to process + * @addr: A pointer to a #sockaddr structure to fill with the mapped address + * that the STUN server gives us + * @addrlen: The length of @add. rMust be set to the size of the @addr socket + * address and will be set to the actual length of the socket address. + * @alternate_server: A pointer to a #sockaddr structure to fill with the + * address of an alternate server to which we should send our new STUN + * binding request, in case the currently used STUN server is requesting the use + * of an alternate server. This argument will only be filled if the return value + * of the function is #STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER + * @alternate_server_len: The length of @alternate_server. Must be set to + * the size of the @alternate_server socket address and will be set to the + * actual length of the socket address. + * + * Process a STUN binding response and extracts the mapped address from the STUN + * message. Also checks for the ALTERNATE-SERVER attribute. + * Returns: A #StunUsageBindReturn value. + * Note that #STUN_USAGE_BIND_RETURN_TIMEOUT cannot be returned by this function + */ +StunUsageBindReturn stun_usage_bind_process (StunMessage *msg, + struct sockaddr *addr, socklen_t *addrlen, + struct sockaddr *alternate_server, socklen_t *alternate_server_len); + +/** + * stun_usage_bind_keepalive: + * @agent: The #StunAgent to use to build the message + * @msg: The #StunMessage to build + * @buf: The buffer to use for creating the #StunMessage + * @len: The size of the @buf + * + * Creates a STUN binding indication that can be used for a keepalive. + * Since this is an indication message, no STUN response will be generated + * and it can only be used as a keepalive message. + * Returns: The length of the message to send + */ +size_t stun_usage_bind_keepalive (StunAgent *agent, StunMessage *msg, + uint8_t *buf, size_t len); + +/** + * stun_usage_bind_run: + * @srv: A pointer to the #sockaddr structure representing the STUN server's + * address + * @srvlen: The length of @srv + * @addr: A pointer to a #sockaddr structure to fill with the mapped address + * that the STUN server gives us + * @addrlen: The length of @addr + * + * This is a convenience function that will do a synchronous Binding request to + * a server and wait for its answer. It will create the socket transports and + * use the #StunTimer usage to send the request and handle the response. + * Returns: A #StunUsageBindReturn. + * Possible return values are #STUN_USAGE_BIND_RETURN_SUCCESS, + * #STUN_USAGE_BIND_RETURN_ERROR and #STUN_USAGE_BIND_RETURN_TIMEOUT + */ +StunUsageBindReturn stun_usage_bind_run (const struct sockaddr *srv, + socklen_t srvlen, struct sockaddr_storage *addr, socklen_t *addrlen); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/linux_x86/include/stun/usages/ice.h b/linux_x86/include/stun/usages/ice.h new file mode 100644 index 0000000..561a0ce --- /dev/null +++ b/linux_x86/include/stun/usages/ice.h @@ -0,0 +1,240 @@ + +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2007-2009 Nokia Corporation. All rights reserved. + * Contact: Rémi Denis-Courmont + * + * 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. + * Rémi Denis-Courmont, Nokia + * + * 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 STUN_CONNCHECK_H +# define STUN_CONNCHECK_H 1 + +/** + * SECTION:ice + * @short_description: STUN ICE Usage + * @include: stun/usages/ice.h + * @stability: Stable + * + * The STUN ICE usage allows for easily creating and parsing STUN Binding + * requests and responses used for ICE connectivity checks. The API allows you + * to create a connectivity check message, parse a response or create a reply + * to an incoming connectivity check request. + */ + +# include "stun/stunagent.h" + +# ifdef __cplusplus +extern "C" { +# endif + +/** + * StunUsageIceCompatibility: + * @STUN_USAGE_ICE_COMPATIBILITY_RFC5245: The ICE compatibility with RFC 5245 + * @STUN_USAGE_ICE_COMPATIBILITY_GOOGLE: The ICE compatibility with Google's + * implementation of ICE + * @STUN_USAGE_ICE_COMPATIBILITY_MSN: The ICE compatibility with MSN's + * implementation of ICE + * @STUN_USAGE_ICE_COMPATIBILITY_MSICE2: The ICE compatibility with [MS-ICE2] + * specification + * @STUN_USAGE_ICE_COMPATIBILITY_DRAFT19: The ICE compatibility with draft 19 + * @STUN_USAGE_ICE_COMPATIBILITY_WLM2009: An alias + * for @STUN_USAGE_ICE_COMPATIBILITY_MSICE2 + * + * This enum defines which compatibility modes this ICE usage can use + * + * @STUN_USAGE_ICE_COMPATIBILITY_DRAFT19 and + * @STUN_USAGE_ICE_COMPATIBILITY_WLM2009 are deprecated and should not be used + * in newly-written code. They are kept for compatibility reasons and represent + * the same compatibilities as @STUN_USAGE_ICE_COMPATIBILITY_RFC5245 and + * @STUN_USAGE_ICE_COMPATIBILITY_MSICE2 respectively. + */ +typedef enum { + STUN_USAGE_ICE_COMPATIBILITY_RFC5245, + STUN_USAGE_ICE_COMPATIBILITY_GOOGLE, + STUN_USAGE_ICE_COMPATIBILITY_MSN, + STUN_USAGE_ICE_COMPATIBILITY_MSICE2, + STUN_USAGE_ICE_COMPATIBILITY_DRAFT19 = STUN_USAGE_ICE_COMPATIBILITY_RFC5245, + STUN_USAGE_ICE_COMPATIBILITY_WLM2009 = STUN_USAGE_ICE_COMPATIBILITY_MSICE2, +} StunUsageIceCompatibility; + + +/** + * StunUsageIceReturn: + * @STUN_USAGE_ICE_RETURN_SUCCESS: The function succeeded + * @STUN_USAGE_ICE_RETURN_ERROR: There was an unspecified error + * @STUN_USAGE_ICE_RETURN_INVALID: The message is invalid for processing + * @STUN_USAGE_ICE_RETURN_ROLE_CONFLICT: A role conflict was detected + * @STUN_USAGE_ICE_RETURN_INVALID_REQUEST: The message is an not a request + * @STUN_USAGE_ICE_RETURN_INVALID_METHOD: The method of the request is invalid + * @STUN_USAGE_ICE_RETURN_MEMORY_ERROR: The buffer size is too small to hold + * the STUN reply + * @STUN_USAGE_ICE_RETURN_INVALID_ADDRESS: The mapped address argument has + * an invalid address family + * @STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS: The response is valid but no + * MAPPED-ADDRESS or XOR-MAPPED-ADDRESS attribute was found + * + * Return value of stun_usage_ice_conncheck_process() and + * stun_usage_ice_conncheck_create_reply() which allows you to see what + * status the function call returned. + */ +typedef enum { + STUN_USAGE_ICE_RETURN_SUCCESS, + STUN_USAGE_ICE_RETURN_ERROR, + STUN_USAGE_ICE_RETURN_INVALID, + STUN_USAGE_ICE_RETURN_ROLE_CONFLICT, + STUN_USAGE_ICE_RETURN_INVALID_REQUEST, + STUN_USAGE_ICE_RETURN_INVALID_METHOD, + STUN_USAGE_ICE_RETURN_MEMORY_ERROR, + STUN_USAGE_ICE_RETURN_INVALID_ADDRESS, + STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS, +} StunUsageIceReturn; + + +/** + * stun_usage_ice_conncheck_create: + * @agent: The #StunAgent to use to build the request + * @msg: The #StunMessage to build + * @buffer: The buffer to use for creating the #StunMessage + * @buffer_len: The size of the @buffer + * @username: The username to use in the request + * @username_len: The length of @username + * @password: The key to use for building the MESSAGE-INTEGRITY + * @password_len: The length of @password + * @cand_use: Set to %TRUE to append the USE-CANDIDATE flag to the request + * @controlling: Set to %TRUE if you are the controlling agent or set to + * %FALSE if you are the controlled agent. + * @priority: The value of the PRIORITY attribute + * @tie: The value of the tie-breaker to put in the ICE-CONTROLLED or + * ICE-CONTROLLING attribute + * @candidate_identifier: The foundation value to put in the + * CANDIDATE-IDENTIFIER attribute + * @compatibility: The compatibility mode to use for building the conncheck + * request + * + * Builds an ICE connectivity check STUN message. + * If the compatibility is not #STUN_USAGE_ICE_COMPATIBILITY_RFC5245, the + * @cand_use, @controlling, @priority and @tie arguments are not used. + * If the compatibility is not #STUN_USAGE_ICE_COMPATIBILITY_MSICE2, the + * @candidate_identifier argument is not used. + * Returns: The length of the message built. + */ +size_t +stun_usage_ice_conncheck_create (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, + const uint8_t *username, const size_t username_len, + const uint8_t *password, const size_t password_len, + bool cand_use, bool controlling, uint32_t priority, + uint64_t tie, const char *candidate_identifier, + StunUsageIceCompatibility compatibility); + + +/** + * stun_usage_ice_conncheck_process: + * @msg: The #StunMessage to process + * @addr: A pointer to a #sockaddr structure to fill with the mapped address + * that the STUN connectivity check response contains + * @addrlen: The length of @addr + * @compatibility: The compatibility mode to use for processing the conncheck + * response + * + * Process an ICE connectivity check STUN message and retrieve the + * mapped address from the message + * See also stun_usage_ice_conncheck_priority() and + * stun_usage_ice_conncheck_use_candidate() + * Returns: A #StunUsageIceReturn value + */ +StunUsageIceReturn stun_usage_ice_conncheck_process (StunMessage *msg, + struct sockaddr_storage *addr, socklen_t *addrlen, + StunUsageIceCompatibility compatibility); + +/** + * stun_usage_ice_conncheck_create_reply: + * @agent: The #StunAgent to use to build the response + * @req: The original STUN request to reply to + * @msg: The #StunMessage to build + * @buf: The buffer to use for creating the #StunMessage + * @plen: A pointer containing the size of the @buffer on input. + * Will contain the length of the message built on output. + * @src: A pointer to a #sockaddr structure containing the source address from + * which the request was received. Will be used as the mapped address in the + * response + * @srclen: The length of @addr + * @control: Set to %TRUE if you are the controlling agent or set to + * %FALSE if you are the controlled agent. + * @tie: The value of the tie-breaker to put in the ICE-CONTROLLED or + * ICE-CONTROLLING attribute + * @compatibility: The compatibility mode to use for building the conncheck + * response + * + * Tries to parse a STUN connectivity check request and builds a + * response accordingly. + + + In case of error, the @msg is filled with the appropriate error response + to be sent and the value of @plen is set to the size of that message. + If @plen has a size of 0, then no error response should be sent. + + + * Returns: A #StunUsageIceReturn value + */ +StunUsageIceReturn +stun_usage_ice_conncheck_create_reply (StunAgent *agent, StunMessage *req, + StunMessage *msg, uint8_t *buf, size_t *plen, + const struct sockaddr_storage *src, socklen_t srclen, + bool *control, uint64_t tie, + StunUsageIceCompatibility compatibility); + +/** + * stun_usage_ice_conncheck_priority: + * @msg: The #StunMessage to parse + * + * Extracts the priority from a STUN message. + * Returns: host byte order priority, or 0 if not specified. + */ +uint32_t stun_usage_ice_conncheck_priority (const StunMessage *msg); + +/** + * stun_usage_ice_conncheck_use_candidate: + * @msg: The #StunMessage to parse + * + * Extracts the USE-CANDIDATE attribute flag from a STUN message. + * Returns: %TRUE if the flag is set, %FALSE if not. + */ +bool stun_usage_ice_conncheck_use_candidate (const StunMessage *msg); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/linux_x86/include/stun/usages/timer.h b/linux_x86/include/stun/usages/timer.h new file mode 100644 index 0000000..097e75b --- /dev/null +++ b/linux_x86/include/stun/usages/timer.h @@ -0,0 +1,240 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2007-2009 Nokia Corporation. All rights reserved. + * Contact: Rémi Denis-Courmont + * + * 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. + * Rémi Denis-Courmont, Nokia + * + * 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 STUN_TIMER_H +# define STUN_TIMER_H 1 + +/** + * SECTION:timer + * @short_description: STUN timer Usage + * @include: stun/usages/timer.h + * @stability: Stable + * + * The STUN timer usage is a set of helpful utility functions that allows you + * to easily track when a STUN message should be retransmitted or considered + * as timed out. + * + * + + Simple example on how to use the timer usage + + StunTimer timer; + unsigned remainder; + StunUsageTimerReturn ret; + + // Build the message, etc.. + ... + + // Send the message and start the timer + send(socket, request, sizeof(request)); + stun_timer_start(&timer, STUN_TIMER_DEFAULT_TIMEOUT, + STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); + + // Loop until we get the response + for (;;) { + remainder = stun_timer_remainder(&timer); + + // Poll the socket until data is received or the timer expires + if (poll (&pollfd, 1, delay) <= 0) { + // Time out and no response was received + ret = stun_timer_refresh (&timer); + if (ret == STUN_USAGE_TIMER_RETURN_TIMEOUT) { + // Transaction timed out + break; + } else if (ret == STUN_USAGE_TIMER_RETURN_RETRANSMIT) { + // A retransmission is necessary + send(socket, request, sizeof(request)); + continue; + } else if (ret == STUN_USAGE_TIMER_RETURN_SUCCESS) { + // The refresh succeeded and nothing has to be done, continue polling + continue; + } + } else { + // We received a response, read it + recv(socket, response, sizeof(response)); + break; + } + } + + // Check if the transaction timed out or not + if (ret == STUN_USAGE_TIMER_RETURN_TIMEOUT) { + // do whatever needs to be done in that case + } else { + // Parse the response + } + + + + */ + +#ifdef _WIN32 +#include +#else +# include +# include +# include +#endif + + +/** + * StunTimer: + * + * An opaque structure representing a STUN transaction retransmission timer + */ +typedef struct stun_timer_s StunTimer; + +struct stun_timer_s { + struct timeval deadline; + unsigned delay; + unsigned retransmissions; + unsigned max_retransmissions; +}; + + +/** + * STUN_TIMER_DEFAULT_TIMEOUT: + * + * The default intial timeout to use for the timer + * RFC recommendds 500, but it's ridiculous, 50ms is known to work in most + * cases as it is also what is used by SIP style VoIP when sending A-Law and + * mu-Law audio, so 200ms should be hyper safe. With an initial timeout + * of 200ms, a default of 7 transmissions, the last timeout will be + * 16 * 200ms, and we expect to receive a response from the stun server + * before (1 + 2 + 4 + 8 + 16 + 32 + 16) * 200ms = 15200 ms after the initial + * stun request has been sent. + */ +#define STUN_TIMER_DEFAULT_TIMEOUT 200 + +/** + * STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS: + * + * The default maximum retransmissions allowed before a timer decides to timeout + */ +#define STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS 7 + +/** + * STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT: + * + * The default intial timeout to use for a reliable timer + */ +#define STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT 7900 + +/** + * StunUsageTimerReturn: + * @STUN_USAGE_TIMER_RETURN_SUCCESS: The timer was refreshed successfully + * and there is nothing to be done + * @STUN_USAGE_TIMER_RETURN_RETRANSMIT: The timer expired and the message + * should be retransmitted now. + * @STUN_USAGE_TIMER_RETURN_TIMEOUT: The timer expired as well as all the + * retransmissions, the transaction timed out + * + * Return value of stun_usage_timer_refresh() which provides you with status + * information on the timer. + */ +typedef enum { + STUN_USAGE_TIMER_RETURN_SUCCESS, + STUN_USAGE_TIMER_RETURN_RETRANSMIT, + STUN_USAGE_TIMER_RETURN_TIMEOUT +} StunUsageTimerReturn; + +# ifdef __cplusplus +extern "C" { +# endif + + +/** + * stun_timer_start: + * @timer: The #StunTimer to start + * @initial_timeout: The initial timeout to use before the first retransmission + * @max_retransmissions: The maximum number of transmissions before the + * #StunTimer times out + * + * Starts a STUN transaction retransmission timer. + * This should be called as soon as you send the message for the first time on + * a UDP socket. + * The timeout before the next retransmission is set to @initial_timeout, then + * each time a packet is retransmited, that timeout will be doubled, until the + * @max_retransmissions retransmissions limit is reached. + * + * To determine the total timeout value, one can use the following equation : + + total_timeout = initial_timeout * (2^(max_retransmissions + 1) - 1); + + * + * + * See also: #STUN_TIMER_DEFAULT_TIMEOUT + * + * See also: #STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS + */ +void stun_timer_start (StunTimer *timer, unsigned int initial_timeout, + unsigned int max_retransmissions); + +/** + * stun_timer_start_reliable: + * @timer: The #StunTimer to start + * @initial_timeout: The initial timeout to use before the first retransmission + * + * Starts a STUN transaction retransmission timer for a reliable transport. + * This should be called as soon as you send the message for the first time on + * a TCP socket + */ +void stun_timer_start_reliable (StunTimer *timer, unsigned int initial_timeout); + +/** + * stun_timer_refresh: + * @timer: The #StunTimer to refresh + * + * Updates a STUN transaction retransmission timer. + * Returns: A #StunUsageTimerReturn telling you what to do next + */ +StunUsageTimerReturn stun_timer_refresh (StunTimer *timer); + +/** + * stun_timer_remainder: + * @timer: The #StunTimer to query + * + * Query the timer on the time left before the next refresh should be done + * Returns: The time remaining for the timer to expire in milliseconds + */ +unsigned stun_timer_remainder (const StunTimer *timer); + +# ifdef __cplusplus +} +# endif + +#endif /* !STUN_TIMER_H */ diff --git a/linux_x86/include/stun/usages/turn.h b/linux_x86/include/stun/usages/turn.h new file mode 100644 index 0000000..83fa00a --- /dev/null +++ b/linux_x86/include/stun/usages/turn.h @@ -0,0 +1,301 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008-2009 Collabora Ltd. + * Contact: Youness Alaoui + * (C) 2007-2009 Nokia Corporation. All rights reserved. + * Contact: Rémi Denis-Courmont + * + * 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. + * Rémi Denis-Courmont, Nokia + * + * 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 STUN_TURN_H +# define STUN_TURN_H 1 + +/** + * SECTION:turn + * @short_description: TURN Allocation Usage + * @include: stun/usages/turn.h + * @stability: Stable + * + * The STUN TURN usage allows for easily creating and parsing STUN Allocate + * requests and responses used for TURN. The API allows you to create a new + * allocation or refresh an existing one as well as to parse a response to + * an allocate or refresh request. + */ + + +#ifdef _WIN32 +# include "../win32_common.h" +#else +# include +# include +#endif + +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +# include "stun/stunagent.h" + +# ifdef __cplusplus +extern "C" { +# endif + +/** + * StunUsageTurnRequestPorts: + * @STUN_USAGE_TURN_REQUEST_PORT_NORMAL: Request a normal port + * @STUN_USAGE_TURN_REQUEST_PORT_EVEN: Request an even port + * @STUN_USAGE_TURN_REQUEST_PORT_EVEN_AND_RESERVE: Request an even port and + * reserve the next higher port + * + * This enum is used to specify which port configuration you want when creating + * a new Allocation + */ +typedef enum { + STUN_USAGE_TURN_REQUEST_PORT_NORMAL = 0, + STUN_USAGE_TURN_REQUEST_PORT_EVEN = 1, + STUN_USAGE_TURN_REQUEST_PORT_EVEN_AND_RESERVE = 2 +} StunUsageTurnRequestPorts; + +/** + * StunUsageTurnCompatibility: + * @STUN_USAGE_TURN_COMPATIBILITY_DRAFT9: Use the specification compatible with + * TURN Draft 09 + * @STUN_USAGE_TURN_COMPATIBILITY_GOOGLE: Use the specification compatible with + * Google Talk's relay server + * @STUN_USAGE_TURN_COMPATIBILITY_MSN: Use the specification compatible with + * MSN TURN servers + * @STUN_USAGE_TURN_COMPATIBILITY_OC2007: Use the specification compatible with + * Microsoft Office Communicator 2007 + * @STUN_USAGE_TURN_COMPATIBILITY_RFC5766: Use the specification compatible with + * RFC 5766 (the final, canonical TURN standard) + * + * Specifies which TURN specification compatibility to use + */ +typedef enum { + STUN_USAGE_TURN_COMPATIBILITY_DRAFT9, + STUN_USAGE_TURN_COMPATIBILITY_GOOGLE, + STUN_USAGE_TURN_COMPATIBILITY_MSN, + STUN_USAGE_TURN_COMPATIBILITY_OC2007, + STUN_USAGE_TURN_COMPATIBILITY_RFC5766, +} StunUsageTurnCompatibility; + +/** + * StunUsageTurnReturn: + * @STUN_USAGE_TURN_RETURN_RELAY_SUCCESS: The response was successful and a relay + * address is provided + * @STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS: The response was successful and a + * relay address as well as a mapped address are provided + * @STUN_USAGE_TURN_RETURN_ERROR: The response resulted in an error + * @STUN_USAGE_TURN_RETURN_INVALID: The response is not a valid response + * @STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER: The server requests the message + * to be sent to an alternate server + * + * Return value of stun_usage_turn_process() and + * stun_usage_turn_refresh_process() which allows you to see what status the + * function call returned. + */ +typedef enum { + STUN_USAGE_TURN_RETURN_RELAY_SUCCESS, + STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS, + STUN_USAGE_TURN_RETURN_ERROR, + STUN_USAGE_TURN_RETURN_INVALID, + STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER, +} StunUsageTurnReturn; + + +/** + * stun_usage_turn_create: + * @agent: The #StunAgent to use to build the request + * @msg: The #StunMessage to build + * @buffer: The buffer to use for creating the #StunMessage + * @buffer_len: The size of the @buffer + * @previous_response: If this is the first request you are sending, set this + * argument to NULL, if it's a subsequent request you are building, then set this + * argument to the response you have received. This argument is used for building + * long term credentials (using the REALM and NONCE attributes) as well as for + * getting the RESERVATION-TOKEN attribute when you previously requested an + * allocation which reserved two ports + * @request_ports: Specify how you want to request the allocated port(s). + * This is only used if the compatibility is set to + * #STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 + * See #StunUsageTurnRequestPorts + * @bandwidth: The bandwidth to request from the server for the allocation. If + * this value is negative, then no BANDWIDTH attribute is added to the request. + * This is only used if the compatibility is set to + * #STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 + * @lifetime: The lifetime of the allocation to request from the server. If + * this value is negative, then no LIFETIME attribute is added to the request. + * This is only used if the compatibility is set to + * #STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 + * @username: The username to use in the request + * @username_len: The length of @username + * @password: The key to use for building the MESSAGE-INTEGRITY + * @password_len: The length of @password + * @compatibility: The compatibility mode to use for building the Allocation + * request + * + * Create a new TURN Allocation request + * Returns: The length of the message to send + */ +size_t stun_usage_turn_create (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, + StunMessage *previous_response, + StunUsageTurnRequestPorts request_ports, + int32_t bandwidth, int32_t lifetime, + uint8_t *username, size_t username_len, + uint8_t *password, size_t password_len, + StunUsageTurnCompatibility compatibility); + +/** + * stun_usage_turn_create_refresh: + * @agent: The #StunAgent to use to build the request + * @msg: The #StunMessage to build + * @buffer: The buffer to use for creating the #StunMessage + * @buffer_len: The size of the @buffer + * @previous_response: If this is the first request you are sending, set this + * argument to NULL, if it's a subsequent request you are building, then set this + * argument to the response you have received. This argument is used for building + * long term credentials (using the REALM and NONCE attributes) + * @lifetime: The lifetime of the allocation to request from the server. If + * this value is negative, then no LIFETIME attribute is added to the request. + * This is only used if the compatibility is set to + * #STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 + * @username: The username to use in the request + * @username_len: The length of @username + * @password: The key to use for building the MESSAGE-INTEGRITY + * @password_len: The length of @password + * @compatibility: The compatibility mode to use for building the Allocation + * request + * + * Create a new TURN Refresh request + * Returns: The length of the message to send + */ +size_t stun_usage_turn_create_refresh (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, + StunMessage *previous_response, int32_t lifetime, + uint8_t *username, size_t username_len, + uint8_t *password, size_t password_len, + StunUsageTurnCompatibility compatibility); + +/** + * stun_usage_turn_create_permission: + * @agent: The #StunAgent to use to build the request + * @msg: The #StunMessage to build + * @buffer: The buffer to use for creating the #StunMessage + * @buffer_len: The size of the @buffer + * @username: The username to use in the request + * @username_len: The length of @username + * @password: The key to use for building the MESSAGE-INTEGRITY + * @password_len: The length of @password + * @realm: The realm identifier to use in the request + * @realm_len: The length of @realm + * @nonce: Unique and securely random nonce to use in the request + * @nonce_len: The length of @nonce + * @peer: Server-reflexive host address to request permission for + * @compatibility: The compatibility mode to use for building the + * CreatePermission request + * + * Create a new TURN CreatePermission request + * + * Returns: The length of the message to send + */ +size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, + uint8_t *username, size_t username_len, + uint8_t *password, size_t password_len, + uint8_t *realm, size_t realm_len, + uint8_t *nonce, size_t nonce_len, + struct sockaddr_storage *peer, + StunUsageTurnCompatibility compatibility); + +/** + * stun_usage_turn_process: + * @msg: The message containing the response + * @relay_addr: A pointer to a #sockaddr structure to fill with the relay address + * that the TURN server allocated for us + * @relay_addrlen: The length of @relay_addr + * @addr: A pointer to a #sockaddr structure to fill with the mapped address + * that the STUN response contains. + * This argument will only be filled if the return value + * of the function is #STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS + * @addrlen: The length of @addr + * @alternate_server: A pointer to a #sockaddr structure to fill with the + * address of an alternate server to which we should send our new STUN + * Allocate request, in case the currently used TURN server is requesting the use + * of an alternate server. This argument will only be filled if the return value + * of the function is #STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER + * In the case of @STUN_USAGE_TURN_COMPATIBILITY_OC2007 compatibility, the + * @alternate_server could be filled at any time, and should only be considered + * if the request was sent to a different server than the address returned + * in the @alternate_server field + * @alternate_server_len: The length of @alternate_server + * @bandwidth: A pointer to fill with the bandwidth the TURN server allocated us + * @lifetime: A pointer to fill with the lifetime of the allocation + * @compatibility: The compatibility mode to use for processing the Allocation + * response + * + * Process a TURN Allocate response and extract the necessary information from + * the message + * Returns: A #StunUsageTurnReturn value + */ +StunUsageTurnReturn stun_usage_turn_process (StunMessage *msg, + struct sockaddr_storage *relay_addr, socklen_t *relay_addrlen, + struct sockaddr_storage *addr, socklen_t *addrlen, + struct sockaddr_storage *alternate_server, socklen_t *alternate_server_len, + uint32_t *bandwidth, uint32_t *lifetime, + StunUsageTurnCompatibility compatibility); + +/** + * stun_usage_turn_refresh_process: + * @msg: The message containing the response + * @lifetime: A pointer to fill with the lifetime of the allocation + * @compatibility: The compatibility mode to use for processing the Refresh + * response + * + * Process a TURN Refresh response and extract the necessary information from + * the message + * Returns: A #StunUsageTurnReturn value. A #STUN_USAGE_TURN_RETURN_RELAY_SUCCESS + * means the Refresh was successful, but no relay address is given (kept the same + * as for the original allocation) + */ +StunUsageTurnReturn stun_usage_turn_refresh_process (StunMessage *msg, + uint32_t *lifetime, StunUsageTurnCompatibility compatibility); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/linux_x86/include/stun/win32_common.h b/linux_x86/include/stun/win32_common.h new file mode 100644 index 0000000..ec833c3 --- /dev/null +++ b/linux_x86/include/stun/win32_common.h @@ -0,0 +1,74 @@ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2008-2009 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. + * Danny Smith + * + * 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. + */ + +/* ISO C9x 7.18 Integer types + * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794) + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * Contributor: Danny Smith + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Date: 2000-12-02 + */ + + +#ifndef _WIN32_COMMON_H +#define _WIN32_COMMON_H + +#include +#include +#include + +/* On MSVC, ssize_t is SSIZE_T */ +#ifdef _MSC_VER +#include +#define ssize_t SSIZE_T +#endif + +/* Windows v10.0.16232 SDK defines MSG_ERRQUEUE, but doesn't support it with + * recvmsg, and also uses a different msghdr struct */ +#undef MSG_ERRQUEUE + +#endif /* _WIN32_COMMON_H */ diff --git a/linux_x86/lib/libnice.la b/linux_x86/lib/libnice.la new file mode 100755 index 0000000..252b800 --- /dev/null +++ b/linux_x86/lib/libnice.la @@ -0,0 +1,41 @@ +# libnice.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libnice.so.10' + +# Names of this library. +library_names='libnice.so.10.9.0 libnice.so.10 libnice.so' + +# The name of the static archive. +old_library='' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='' + +# Libraries that this one depends upon. +dependency_libs=' -L/root/libnice/../boringssl/crypto/ -L/root/libnice/../boringssl/ssl/ -lrt -lz -lpthread -ldl -lresolv -lcrypto -lssl' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libnice. +current=19 +age=9 +revision=0 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/root/libnice/packages/lib' diff --git a/linux_x86/lib/libnice.so b/linux_x86/lib/libnice.so new file mode 120000 index 0000000..ab8669e --- /dev/null +++ b/linux_x86/lib/libnice.so @@ -0,0 +1 @@ +libnice.so.10.9.0 \ No newline at end of file diff --git a/linux_x86/lib/libnice.so.10 b/linux_x86/lib/libnice.so.10 new file mode 120000 index 0000000..ab8669e --- /dev/null +++ b/linux_x86/lib/libnice.so.10 @@ -0,0 +1 @@ +libnice.so.10.9.0 \ No newline at end of file diff --git a/linux_x86/lib/libnice.so.10.9.0 b/linux_x86/lib/libnice.so.10.9.0 new file mode 100755 index 0000000..be3be97 Binary files /dev/null and b/linux_x86/lib/libnice.so.10.9.0 differ diff --git a/linux_x86/lib/pkgconfig/nice.pc b/linux_x86/lib/pkgconfig/nice.pc new file mode 100644 index 0000000..1ee51ce --- /dev/null +++ b/linux_x86/lib/pkgconfig/nice.pc @@ -0,0 +1,13 @@ +prefix=/root/libnice/packages +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include +upnp_enabled= + +Name: libnice +Description: ICE library +Version: 0.1.16.1 +Requires: glib-2.0 >= 2.54 gio-2.0 >= 2.54 gobject-2.0 >= 2.54 +Requires.private: gthread-2.0 libcrypto +Libs: -L${libdir} -lnice +Cflags: -I${includedir}/nice -I${includedir}