Can be useful to know which STUN server was used to discover the given candidate.
&externaddr,
host_candidate->c.transport,
host_candidate->sockptr,
+ NULL,
TRUE);
check_upnp_gathering_done (agent, stream);
* of type %NICE_CANDIDATE_TYPE_RELAYED
* @sockptr: The underlying socket
* @keepalive_next_tick: The timestamp for the next keepalive
+ * @stun_server: The STUN server address, if the candidate is
+ * of type %NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE
*
* A structure to represent an ICE candidate
*/
TurnServer *turn;
NiceSocket *sockptr;
guint64 keepalive_next_tick; /* next tick timestamp */
+ NiceAddress *stun_server;
};
if (c->turn)
turn_server_unref (c->turn);
+ if (c->stun_server)
+ nice_address_free (c->stun_server);
+
g_slice_free (NiceCandidateImpl, c);
}
*addr = c->turn->server;
}
+
+NICEAPI_EXPORT gboolean
+nice_candidate_stun_server_address (const NiceCandidate *candidate, NiceAddress *addr)
+{
+ const NiceCandidateImpl *c = (NiceCandidateImpl *) candidate;
+
+ g_return_val_if_fail (candidate != NULL, FALSE);
+ g_return_val_if_fail (candidate->type != NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE, FALSE);
+
+ if (c->stun_server) {
+ *addr = *c->stun_server;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
/**
* NiceCandidateType:
* @NICE_CANDIDATE_TYPE_HOST: A host candidate
- * @NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: A server reflexive candidate
+ * @NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: A server reflexive candidate (or a NAT-assisted 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
+ * An enum representing the type of a candidate
*/
typedef enum
{
nice_candidate_relay_address (const NiceCandidate *candidate, NiceAddress *addr);
/**
+ * nice_candidate_stun_server_address:
+ * @candidate: A server-reflexive candidate
+ * @addr: The #NiceAddress to fill
+ *
+ * In case the given candidate server-reflexive, use this utility function to get its address. The
+ * address will be filled only if the candidate was generated using an STUN server.
+ *
+ * Returns: TRUE if it's a STUN created ICE candidate, or FALSE if the reflexed's server was not STUN.
+ *
+ * Since: 0.1.20
+ */
+gboolean
+nice_candidate_stun_server_address (const NiceCandidate *candidate, NiceAddress *addr);
+
+/**
* NICE_TYPE_CANDIDATE:
*
* A boxed type for a #NiceCandidate.
*
* @return TRUE if a matching transaction is found
*/
-static gboolean priv_map_reply_to_discovery_request (NiceAgent *agent, StunMessage *resp)
+static gboolean priv_map_reply_to_discovery_request (NiceAgent *agent, StunMessage *resp, const NiceAddress *server_address)
{
union {
struct sockaddr_storage storage;
&niceaddr,
NICE_CANDIDATE_TRANSPORT_UDP,
d->nicesock,
+ server_address,
FALSE);
+
if (agent->use_ice_tcp)
discovery_discover_tcp_server_reflexive_candidates (
agent,
d->stream_id,
d->component_id,
&niceaddr,
- d->nicesock);
+ d->nicesock,
+ server_address);
}
d->stun_message.buffer = NULL;
d->stun_message.buffer_len = 0;
&mappedniceaddr,
NICE_CANDIDATE_TRANSPORT_UDP,
d->nicesock,
+ &niceaddr,
FALSE);
}
if (agent->use_ice_tcp) {
d->stream_id,
d->component_id,
&mappedniceaddr,
- d->nicesock);
+ d->nicesock,
+ &niceaddr);
}
}
}
/* step: let's try to match the response to an existing discovery */
if (trans_found != TRUE)
- trans_found = priv_map_reply_to_discovery_request (agent, &req);
+ trans_found = priv_map_reply_to_discovery_request (agent, &req, from);
/* step: let's try to match the response to an existing turn allocate */
if (trans_found != TRUE)
*
* @return pointer to the created candidate, or NULL on error
*/
-NiceCandidate*
+void
discovery_add_server_reflexive_candidate (
NiceAgent *agent,
guint stream_id,
NiceAddress *address,
NiceCandidateTransport transport,
NiceSocket *base_socket,
+ const NiceAddress *server_address,
gboolean nat_assisted)
{
NiceCandidate *candidate;
gboolean result = FALSE;
if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
- return NULL;
+ return;
candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE);
c = (NiceCandidateImpl *) candidate;
agent->reliable, nat_assisted);
}
+ if (server_address != NULL)
+ c->stun_server = nice_address_dup (server_address);
+
priv_generate_candidate_credentials (agent, candidate);
priv_assign_foundation (agent, candidate);
/* error: duplicate candidate */
nice_candidate_free (candidate), candidate = NULL;
}
-
- return candidate;
}
/*
guint stream_id,
guint component_id,
NiceAddress *address,
- NiceSocket *base_socket)
+ NiceSocket *base_socket,
+ const NiceAddress *server_addr)
{
NiceComponent *component;
NiceStream *stream;
address,
c->transport,
((NiceCandidateImpl *) c)->sockptr,
+ server_addr,
FALSE);
}
}
TurnServer *turn,
uint32_t *lifetime);
-NiceCandidate*
+void
discovery_add_server_reflexive_candidate (
NiceAgent *agent,
guint stream_id,
NiceAddress *address,
NiceCandidateTransport transport,
NiceSocket *base_socket,
+ const NiceAddress *server_address,
gboolean nat_assisted);
void
guint stream_id,
guint component_id,
NiceAddress *address,
- NiceSocket *base_socket);
+ NiceSocket *base_socket,
+ const NiceAddress *server_address);
NiceCandidate*
discovery_add_peer_reflexive_candidate (
nice_candidate_transport_to_string
nice_candidate_type_to_string
nice_candidate_relay_address
+nice_candidate_stun_server_address
<SUBSECTION Standard>
NICE_TYPE_CANDIDATE
nice_candidate_get_type
nice_candidate_type_get_type
nice_candidate_type_to_string
nice_candidate_relay_address
+nice_candidate_stun_server_address
nice_compatibility_get_type
nice_component_state_get_type
nice_component_state_to_string