Beispiel #1
0
bool NiceConnection::setRemoteCandidates(
    std::vector<CandidateInfo> &candidates) {

    ELOG_DEBUG("Setting remote candidates %d", candidates.size());


    for (unsigned int compId = 1; compId <= iceComponents_; compId++) {

        GSList* candList = NULL;

        for (unsigned int it = 0; it < candidates.size(); it++) {
            NiceCandidateType nice_cand_type;
            CandidateInfo cinfo = candidates[it];
            if (cinfo.mediaType != this->mediaType
                    || this->transportName->compare(cinfo.transProtocol)
                    || cinfo.componentId != compId)
                continue;

            switch (cinfo.hostType) {
            case HOST:
                nice_cand_type = NICE_CANDIDATE_TYPE_HOST;
                break;
            case SRLFX:
                nice_cand_type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE;
                break;
            case PRFLX:
                nice_cand_type = NICE_CANDIDATE_TYPE_PEER_REFLEXIVE;
                break;
            case RELAY:
                nice_cand_type = NICE_CANDIDATE_TYPE_RELAYED;
                break;
            default:
                nice_cand_type = NICE_CANDIDATE_TYPE_HOST;
                break;
            }

            NiceCandidate* thecandidate = nice_candidate_new(nice_cand_type);
            NiceAddress* naddr = nice_address_new();
            nice_address_set_from_string(naddr, cinfo.hostAddress.c_str());
            nice_address_set_port(naddr, cinfo.hostPort);
            thecandidate->addr = *naddr;
            sprintf(thecandidate->foundation, "%s", cinfo.foundation.c_str());

            thecandidate->username = strdup(cinfo.username.c_str());
            thecandidate->password = strdup(cinfo.password.c_str());
            thecandidate->stream_id = (guint) 1;
            thecandidate->component_id = cinfo.componentId;
            thecandidate->priority = cinfo.priority;
            thecandidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
            candList = g_slist_append(candList, thecandidate);
            ELOG_DEBUG("New Candidate SET %s %d", cinfo.hostAddress.c_str(), cinfo.hostPort);

        }
        nice_agent_set_remote_candidates(agent_, (guint) 1, compId, candList);
    }

    ELOG_DEBUG("Candidates SET");
    this->updateIceState(NICE_CANDIDATES_RECEIVED);
    return true;
}
Beispiel #2
0
/*
 * Creates a server reflexive candidate for 'component_id' of stream
 * 'stream_id'.
 *
 * @return pointer to the created candidate, or NULL on error
 */
NiceCandidate*
discovery_add_server_reflexive_candidate (
  NiceAgent *agent,
  guint stream_id,
  guint component_id,
  NiceAddress *address,
  NiceCandidateTransport transport,
  NiceSocket *base_socket,
  gboolean nat_assisted)
{
  NiceCandidate *candidate;
  NiceComponent *component;
  NiceStream *stream;
  gboolean result = FALSE;

  if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
    return NULL;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE);
  candidate->transport = transport;
  candidate->stream_id = stream_id;
  candidate->component_id = component_id;
  candidate->addr = *address;

  /* step: link to the base candidate+socket */
  candidate->sockptr = base_socket;
  candidate->base_addr = base_socket->addr;

  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, nat_assisted);
  } else {
    candidate->priority =  nice_candidate_ice_priority (candidate,
        agent->reliable, nat_assisted);
  }

  candidate->priority = ensure_unique_priority (component,
      candidate->priority);
  priv_generate_candidate_credentials (agent, candidate);
  priv_assign_foundation (agent, candidate);

  result = priv_add_local_candidate_pruned (agent, stream_id, component, candidate);
  if (result) {
    agent_signal_new_candidate (agent, candidate);
  }
  else {
    /* error: duplicate candidate */
    nice_candidate_free (candidate), candidate = NULL;
  }

  return candidate;
}
Beispiel #3
0
/*
 * Copies a candidate
 */
NICEAPI_EXPORT NiceCandidate *
nice_candidate_copy (const NiceCandidate *candidate)
{
  NiceCandidate *copy = nice_candidate_new (candidate->type);

  memcpy (copy, candidate, sizeof(NiceCandidate));

  copy->username = g_strdup (copy->username);
  copy->password = g_strdup (copy->password);

  return copy;
}
Beispiel #4
0
static NiceCandidate *
parse_candidate(char *scand, guint stream_id)
{
  NiceCandidate *cand = NULL;
  NiceCandidateType ntype;
  gchar **tokens = NULL;
  guint i;

  tokens = g_strsplit (scand, ",", 5);
  for (i = 0; tokens[i]; i++);
  if (i != 5)
    goto end;

  for (i = 0; i < G_N_ELEMENTS (candidate_type_name); i++) {
    if (strcmp(tokens[4], candidate_type_name[i]) == 0) {
      ntype = i;
      break;
    }
  }
  if (i == G_N_ELEMENTS (candidate_type_name))
    goto end;

  cand = nice_candidate_new(ntype);
  cand->component_id = 1;
  cand->stream_id = stream_id;
  cand->transport = NICE_CANDIDATE_TRANSPORT_UDP;
  strncpy(cand->foundation, tokens[0], NICE_CANDIDATE_MAX_FOUNDATION);
  cand->foundation[NICE_CANDIDATE_MAX_FOUNDATION - 1] = 0;
  cand->priority = atoi (tokens[1]);

  if (!nice_address_set_from_string(&cand->addr, tokens[2])) {
    g_message("failed to parse addr: %s", tokens[2]);
    nice_candidate_free(cand);
    cand = NULL;
    goto end;
  }

  nice_address_set_port(&cand->addr, atoi (tokens[3]));

 end:
  g_strfreev(tokens);

  return cand;
}
Beispiel #5
0
static void add_bad_candidate (NiceAgent *agent, guint stream_id, NiceCandidate *cand)
{
  NiceAddress bad_addr;
  GSList *cand_list = NULL;

  g_assert (nice_address_set_from_string (&bad_addr, "172.1.0.1"));

  cand = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST);
  cand->stream_id = stream_id;
  cand->component_id = NICE_COMPONENT_TYPE_RTP;
  cand->addr = bad_addr;

  nice_agent_get_local_credentials (agent, stream_id,
                                    &cand->username, &cand->password);
  cand_list = g_slist_prepend (cand_list, cand);

  g_debug ("Adding buggy candidate to the agent %p", agent);
  g_assert (nice_agent_set_remote_candidates (agent, stream_id,
                                    NICE_COMPONENT_TYPE_RTP,
                                    cand_list));

  g_slist_free_full (cand_list, (GDestroyNotify) nice_candidate_free);

}
Beispiel #6
0
nsresult
createNiceCandidate(otIICECandidate *aCandidate, PRUint32 aStreamID,
                    NiceCandidate **_retval)
{
  nsresult res;
  PRInt16 val16;
  PRUint32 val32;
  nsCString valStr;
  NiceCandidate *cand;

  res = aCandidate->GetType(&val16);
  if (NS_FAILED(res))
    return res;

  cand = nice_candidate_new((NiceCandidateType)val16);

  cand->transport = NICE_CANDIDATE_TRANSPORT_UDP;

  res = aCandidate->GetIp(valStr);
  if (NS_FAILED(res))
    goto fail;

  nice_address_set_from_string(&cand->addr, valStr.get());

  res = aCandidate->GetPort(&val32);
  if (NS_FAILED(res))
    goto fail;

  nice_address_set_port(&cand->addr, val32);

  res = aCandidate->GetPriority(&val32);
  if (NS_FAILED(res))
    goto fail;
  cand->priority = val32;

  cand->stream_id = aStreamID;

  res = aCandidate->GetComponent(&val32);
  if (NS_FAILED(res))
    goto fail;
  cand->component_id = val32;

  res = aCandidate->GetFoundation(valStr);
  if (NS_FAILED(res))
    goto fail;
  strncpy(cand->foundation, valStr.get(), NICE_CANDIDATE_MAX_FOUNDATION);

  res = aCandidate->GetUfrag(valStr);
  if (NS_FAILED(res))
    goto fail;
  if (!valStr.IsEmpty())
    cand->username = strdup(valStr.get());

  res = aCandidate->GetPwd(valStr);
  if (NS_FAILED(res))
    goto fail;
  if (!valStr.IsEmpty())
    cand->password = strdup(valStr.get());

  res = aCandidate->GetRelIp(valStr);
  if (NS_FAILED(res))
    goto fail;

  if (!valStr.IsEmpty()) {
    nice_address_set_from_string(&cand->base_addr, valStr.get());

    res = aCandidate->GetRelPort(&val32);
    if (NS_FAILED(res))
      goto fail;

    nice_address_set_port(&cand->base_addr, val32);
  }

  *_retval = cand;

  return NS_OK;

fail:
  nice_candidate_free(cand);
  return res;
}
Beispiel #7
0
GSList* soy_net_xmpp_agent_get_remote_candidates (soynetXMPPAgent* self, LmMessageNode* transport, guint stream_id) {
	GSList* result = NULL;
	GSList* rcands = NULL;
	LmMessageNode* candidate = NULL;
	LmMessageNode* _tmp0_ = NULL;
	LmMessageNode* _tmp1_ = NULL;
	LmMessageNode* _tmp2_ = NULL;
	LmMessageNode* _tmp3_ = NULL;
	GSList* _tmp45_ = NULL;
	GSList* _tmp46_ = NULL;
#line 119 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	g_return_val_if_fail (self != NULL, NULL);
#line 119 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	g_return_val_if_fail (transport != NULL, NULL);
#line 120 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	rcands = NULL;
#line 121 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	_tmp0_ = transport;
#line 121 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	_tmp1_ = lm_message_node_get_child (_tmp0_, "candidate");
#line 121 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	_tmp2_ = _lm_message_node_ref0 (_tmp1_);
#line 121 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	candidate = _tmp2_;
#line 124 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	_tmp3_ = candidate;
#line 124 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	if (_tmp3_ == NULL) {
#line 125 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		result = rcands;
#line 125 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_lm_message_node_unref0 (candidate);
#line 125 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		return result;
#line 584 "XMPPAgent.c"
	}
#line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	while (TRUE) {
#line 588 "XMPPAgent.c"
		LmMessageNode* _tmp4_ = NULL;
		NiceCandidate* rcand = NULL;
		GeeHashMap* _tmp5_ = NULL;
		LmMessageNode* _tmp6_ = NULL;
		const gchar* _tmp7_ = NULL;
		gpointer _tmp8_ = NULL;
		NiceCandidate* _tmp9_ = NULL;
		LmMessageNode* _tmp10_ = NULL;
		const gchar* _tmp11_ = NULL;
		LmMessageNode* _tmp12_ = NULL;
		const gchar* _tmp13_ = NULL;
		LmMessageNode* _tmp14_ = NULL;
		const gchar* _tmp15_ = NULL;
		LmMessageNode* _tmp16_ = NULL;
		const gchar* _tmp17_ = NULL;
		NiceCandidate* _tmp18_ = NULL;
		LmMessageNode* _tmp19_ = NULL;
		const gchar* _tmp20_ = NULL;
		NiceCandidate* _tmp21_ = NULL;
		LmMessageNode* _tmp22_ = NULL;
		const gchar* _tmp23_ = NULL;
		gint _tmp24_ = 0;
		NiceCandidate* _tmp25_ = NULL;
		NiceCandidate* _tmp26_ = NULL;
		LmMessageNode* _tmp27_ = NULL;
		const gchar* _tmp28_ = NULL;
		gint _tmp29_ = 0;
		NiceCandidate* _tmp30_ = NULL;
		LmMessageNode* _tmp31_ = NULL;
		const gchar* _tmp32_ = NULL;
		gint _tmp33_ = 0;
		NiceCandidate* _tmp34_ = NULL;
		guint _tmp35_ = 0U;
		NiceCandidate* _tmp36_ = NULL;
		gboolean _tmp37_ = FALSE;
		gchar* _tmp38_ = NULL;
		gchar* _tmp39_ = NULL;
		NiceCandidate* _tmp40_ = NULL;
		NiceCandidate* _tmp41_ = NULL;
		LmMessageNode* _tmp42_ = NULL;
		LmMessageNode* _tmp43_ = NULL;
		LmMessageNode* _tmp44_ = NULL;
#line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp4_ = candidate;
#line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		if (!(_tmp4_ != NULL)) {
#line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
			break;
#line 637 "XMPPAgent.c"
		}
#line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp5_ = soy_net_xmpp_agent_candidate_type_dict;
#line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp6_ = candidate;
#line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp7_ = lm_message_node_get_attribute (_tmp6_, "type");
#line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp8_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp5_, _tmp7_);
#line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp9_ = nice_candidate_new ((guint) ((gint) ((gintptr) _tmp8_)));
#line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		rcand = _tmp9_;
#line 131 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		g_print ("Remote Candidate\n");
#line 132 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp10_ = candidate;
#line 132 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp11_ = lm_message_node_get_attribute (_tmp10_, "ip");
#line 132 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		g_print ("%s\n", _tmp11_);
#line 133 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp12_ = candidate;
#line 133 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp13_ = lm_message_node_get_attribute (_tmp12_, "port");
#line 133 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		g_print ("port: %s\n", _tmp13_);
#line 134 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp14_ = candidate;
#line 134 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp15_ = lm_message_node_get_attribute (_tmp14_, "priority");
#line 134 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		g_print ("priority:  %s\n", _tmp15_);
#line 135 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp16_ = candidate;
#line 135 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp17_ = lm_message_node_get_attribute (_tmp16_, "component");
#line 135 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		g_print ("component %s\n", _tmp17_);
#line 138 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp18_ = rcand;
#line 138 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp19_ = candidate;
#line 138 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp20_ = lm_message_node_get_attribute (_tmp19_, "ip");
#line 138 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		nice_address_set_from_string (&_tmp18_->addr, _tmp20_);
#line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp21_ = rcand;
#line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp22_ = candidate;
#line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp23_ = lm_message_node_get_attribute (_tmp22_, "port");
#line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp24_ = atoi (_tmp23_);
#line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		nice_address_set_port (&_tmp21_->addr, (guint) _tmp24_);
#line 140 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp25_ = rcand;
#line 140 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp25_->transport = NICE_CANDIDATE_TRANSPORT_UDP;
#line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp26_ = rcand;
#line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp27_ = candidate;
#line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp28_ = lm_message_node_get_attribute (_tmp27_, "priority");
#line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp29_ = atoi (_tmp28_);
#line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp26_->priority = (guint32) _tmp29_;
#line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp30_ = rcand;
#line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp31_ = candidate;
#line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp32_ = lm_message_node_get_attribute (_tmp31_, "component");
#line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp33_ = atoi (_tmp32_);
#line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp30_->component_id = (guint) _tmp33_;
#line 143 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp34_ = rcand;
#line 143 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp35_ = stream_id;
#line 143 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp34_->stream_id = _tmp35_;
#line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp36_ = rcand;
#line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp37_ = nice_address_is_valid (&_tmp36_->addr);
#line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp38_ = bool_to_string (_tmp37_);
#line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp39_ = _tmp38_;
#line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		g_print ("%s\n", _tmp39_);
#line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_g_free0 (_tmp39_);
#line 146 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp40_ = rcand;
#line 146 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp41_ = nice_candidate_copy (_tmp40_);
#line 146 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		rcands = g_slist_append (rcands, _tmp41_);
#line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp42_ = candidate;
#line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp43_ = _tmp42_->next;
#line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_tmp44_ = _lm_message_node_ref0 (_tmp43_);
#line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_lm_message_node_unref0 (candidate);
#line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		candidate = _tmp44_;
#line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
		_nice_candidate_free0 (rcand);
#line 755 "XMPPAgent.c"
	}
#line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	_tmp45_ = rcands;
#line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	_tmp46_ = g_slist_copy (_tmp45_);
#line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	result = _tmp46_;
#line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	_lm_message_node_unref0 (candidate);
#line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	_g_slist_free0 (rcands);
#line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs"
	return result;
#line 769 "XMPPAgent.c"
}
Beispiel #8
0
NiceCandidate * _owr_candidate_to_nice_candidate(OwrCandidate *candidate)
{
    OwrCandidatePrivate *priv;
    NiceCandidate *nice_candidate;
    NiceCandidateType candidate_type;
    NiceComponentType component_type;
    NiceCandidateTransport transport;

    g_return_val_if_fail(candidate, NULL);

    priv = candidate->priv;

    switch (priv->type) {
    case OWR_CANDIDATE_TYPE_HOST:
        candidate_type = NICE_CANDIDATE_TYPE_HOST;
        break;

    case OWR_CANDIDATE_TYPE_SERVER_REFLEXIVE:
        candidate_type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE;
        break;

    case OWR_CANDIDATE_TYPE_PEER_REFLEXIVE:
        candidate_type = NICE_CANDIDATE_TYPE_PEER_REFLEXIVE;
        break;

    case OWR_CANDIDATE_TYPE_RELAY:
        candidate_type = NICE_CANDIDATE_TYPE_RELAYED;
        break;

    default:
        g_return_val_if_reached(NULL);
    }

    switch (priv->component_type) {
    case OWR_COMPONENT_TYPE_RTP:
        component_type = NICE_COMPONENT_TYPE_RTP;
        break;

    case OWR_COMPONENT_TYPE_RTCP:
        component_type = NICE_COMPONENT_TYPE_RTCP;
        break;

    default:
        g_return_val_if_reached(NULL);
    }

    switch (priv->transport_type) {
    case OWR_TRANSPORT_TYPE_UDP:
        transport = NICE_CANDIDATE_TRANSPORT_UDP;
        break;

    case OWR_TRANSPORT_TYPE_TCP_ACTIVE:
        transport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE;
        break;

    case OWR_TRANSPORT_TYPE_TCP_PASSIVE:
        transport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE;
        break;

    case OWR_TRANSPORT_TYPE_TCP_SO:
        transport = NICE_CANDIDATE_TRANSPORT_TCP_SO;
        break;

    default:
        g_return_val_if_reached(NULL);
    }

    g_return_val_if_fail(priv->address && strlen(priv->address) > 0, NULL);
    g_return_val_if_fail(priv->port || transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE, NULL);

    nice_candidate = nice_candidate_new(candidate_type);
    nice_candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
    nice_candidate->component_id = component_type;
    nice_candidate->transport = transport;

    nice_address_set_from_string(&nice_candidate->addr, priv->address);
    nice_address_set_port(&nice_candidate->addr, priv->port);

    if (priv->base_address && strlen(priv->base_address) > 0)
        nice_address_set_from_string(&nice_candidate->base_addr, priv->base_address);
    if (priv->base_port)
        nice_address_set_port(&nice_candidate->base_addr, priv->base_port);

    if (priv->foundation && strlen(priv->foundation) > 0) {
        g_strlcpy((gchar *)&nice_candidate->foundation, priv->foundation,
            MIN(NICE_CANDIDATE_MAX_FOUNDATION, 1 + strlen(priv->foundation)));
    }

    nice_candidate->priority = candidate->priv->priority;

    if (priv->ufrag && strlen(priv->ufrag) > 0)
        nice_candidate->username = g_strdup(priv->ufrag);
    if (priv->password && strlen(priv->password) > 0)
        nice_candidate->password = g_strdup(priv->password);

    return nice_candidate;
}
Beispiel #9
0
  bool NiceConnection::setRemoteCandidates(
      std::vector<CandidateInfo> &candidates) {
    if(agent_==NULL){
      running_=false;
      return false;
    }

    ELOG_DEBUG("Setting remote candidates %lu", candidates.size());
    for (unsigned int compId = 1; compId <= iceComponents_; compId++) {

      GSList* candList = NULL;

      for (unsigned int it = 0; it < candidates.size(); it++) {
        NiceCandidateType nice_cand_type;
        CandidateInfo cinfo = candidates[it];
        if (cinfo.mediaType != this->mediaType
            || cinfo.componentId != compId)
          continue;

        switch (cinfo.hostType) {
          case HOST:
            nice_cand_type = NICE_CANDIDATE_TYPE_HOST;
            break;
          case SRFLX:
            nice_cand_type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE;
            break;
          case PRFLX:
            nice_cand_type = NICE_CANDIDATE_TYPE_PEER_REFLEXIVE;
            break;
          case RELAY:
            nice_cand_type = NICE_CANDIDATE_TYPE_RELAYED;
            break;
          default:
            nice_cand_type = NICE_CANDIDATE_TYPE_HOST;
            break;
        }
        NiceCandidate* thecandidate = nice_candidate_new(nice_cand_type);
        sprintf(thecandidate->foundation, "%s", cinfo.foundation.c_str());
        thecandidate->username = strdup(cinfo.username.c_str());
        thecandidate->password = strdup(cinfo.password.c_str());
        thecandidate->stream_id = (guint) 1;
        thecandidate->component_id = cinfo.componentId;
        thecandidate->priority = cinfo.priority;
        thecandidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
        nice_address_set_from_string(&thecandidate->addr, cinfo.hostAddress.c_str());
        nice_address_set_port(&thecandidate->addr, cinfo.hostPort);
        
        if (cinfo.hostType == RELAY||cinfo.hostType==SRFLX){
          nice_address_set_from_string(&thecandidate->base_addr, cinfo.rAddress.c_str());
          nice_address_set_port(&thecandidate->base_addr, cinfo.rPort);
          ELOG_DEBUG("Adding remote candidate type %d addr %s port %d raddr %s rport %d", cinfo.hostType, cinfo.hostAddress.c_str(), cinfo.hostPort,
              cinfo.rAddress.c_str(), cinfo.rPort);
        }else{
          ELOG_DEBUG("Adding remote candidate type %d addr %s port %d", cinfo.hostType, cinfo.hostAddress.c_str(), cinfo.hostPort);
        }
        candList = g_slist_prepend(candList, thecandidate);
      }

      nice_agent_set_remote_candidates(agent_, (guint) 1, compId, candList);
      g_slist_free_full(candList, (GDestroyNotify)&nice_candidate_free);
    }

    ELOG_DEBUG("Finished setting candidates\n");
    this->updateIceState(NICE_CANDIDATES_RECEIVED);
    return true;
  }
Beispiel #10
0
int janus_sdp_parse_candidate(janus_ice_stream *stream, const char *candidate, int trickle) {
	if(stream == NULL || candidate == NULL)
		return -1;
	janus_ice_handle *handle = stream->handle;
	if(handle == NULL)
		return -2;
	janus_mutex_lock(&handle->mutex);
	janus_ice_component *component = NULL;
	if(strstr(candidate, "candidate:") == candidate) {
		/* Skipping the 'candidate:' prefix Firefox puts in trickle candidates */
		candidate += strlen("candidate:");
	}
	char rfoundation[32], rtransport[4], rip[40], rtype[6], rrelip[40];
	guint32 rcomponent, rpriority, rport, rrelport;
	int res = sscanf(candidate, "%31s %30u %3s %30u %39s %30u typ %5s %*s %39s %*s %30u",
		rfoundation, &rcomponent, rtransport, &rpriority,
			rip, &rport, rtype, rrelip, &rrelport);
	if(res < 7) {
		/* Failed to parse this address, can it be IPv6? */
		if(!janus_ice_is_ipv6_enabled()) {
			JANUS_LOG(LOG_WARN, "[%"SCNu64"] Received IPv6 candidate, but IPv6 support is disabled...\n", handle->handle_id);
			janus_mutex_unlock(&handle->mutex);
			return res;
		}
	}
	if(res >= 7) {
		/* Add remote candidate */
		component = g_hash_table_lookup(stream->components, GUINT_TO_POINTER(rcomponent));
		if(component == NULL) {
			if(rcomponent == 2 && janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_RTCPMUX)) {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"]   -- Skipping component %d in stream %d (rtcp-muxing)\n", handle->handle_id, rcomponent, stream->stream_id);
			} else {
				JANUS_LOG(LOG_ERR, "[%"SCNu64"]   -- No such component %d in stream %d?\n", handle->handle_id, rcomponent, stream->stream_id);
			}
		} else {
			if(rcomponent == 2 && janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_RTCPMUX)) {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"]   -- Skipping component %d in stream %d (rtcp-muxing)\n", handle->handle_id, rcomponent, stream->stream_id);
				janus_mutex_unlock(&handle->mutex);
				return 0;
			}
			//~ if(trickle) {
				//~ if(component->dtls != NULL) {
					//~ /* This component is already ready, ignore this further candidate */
					//~ JANUS_LOG(LOG_VERB, "[%"SCNu64"]   -- Ignoring this candidate, the component is already ready\n", handle->handle_id);
					//~ janus_mutex_unlock(&handle->mutex);
					//~ return 0;
				//~ }
			//~ }
			component->component_id = rcomponent;
			component->stream_id = stream->stream_id;
			NiceCandidate *c = NULL;
			if(!strcasecmp(rtype, "host")) {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"]  Adding remote candidate component:%d stream:%d type:host %s:%d\n",
					handle->handle_id, rcomponent, stream->stream_id, rip, rport);
				/* Unless this is libnice >= 0.1.8, we only support UDP... */
				if(!strcasecmp(rtransport, "udp")) {
					c = nice_candidate_new(NICE_CANDIDATE_TYPE_HOST);
#ifdef HAVE_LIBNICE_TCP
				} else if(!strcasecmp(rtransport, "tcp") && janus_ice_is_ice_tcp_enabled()) {
					c = nice_candidate_new(NICE_CANDIDATE_TYPE_HOST);
#endif
				} else {
					JANUS_LOG(LOG_VERB, "[%"SCNu64"]    Skipping unsupported transport '%s' for media\n", handle->handle_id, rtransport);
				}
			} else if(!strcasecmp(rtype, "srflx")) {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"]  Adding remote candidate component:%d stream:%d type:srflx %s:%d --> %s:%d \n",
					handle->handle_id, rcomponent, stream->stream_id,  rrelip, rrelport, rip, rport);
				/* Unless this is libnice >= 0.1.8, we only support UDP... */
				if(!strcasecmp(rtransport, "udp")) {
					c = nice_candidate_new(NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE);
#ifdef HAVE_LIBNICE_TCP
				} else if(!strcasecmp(rtransport, "tcp") && janus_ice_is_ice_tcp_enabled()) {
					c = nice_candidate_new(NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE);
#endif
				} else {
					JANUS_LOG(LOG_VERB, "[%"SCNu64"]    Skipping unsupported transport '%s' for media\n", handle->handle_id, rtransport);
				}
			} else if(!strcasecmp(rtype, "prflx")) {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"]  Adding remote candidate component:%d stream:%d type:prflx %s:%d --> %s:%d\n",
					handle->handle_id, rcomponent, stream->stream_id, rrelip, rrelport, rip, rport);
				/* Unless this is libnice >= 0.1.8, we only support UDP... */
				if(!strcasecmp(rtransport, "udp")) {
					c = nice_candidate_new(NICE_CANDIDATE_TYPE_PEER_REFLEXIVE);
#ifdef HAVE_LIBNICE_TCP
				} else if(!strcasecmp(rtransport, "tcp") && janus_ice_is_ice_tcp_enabled()) {
					c = nice_candidate_new(NICE_CANDIDATE_TYPE_PEER_REFLEXIVE);
#endif
				} else {
					JANUS_LOG(LOG_VERB, "[%"SCNu64"]    Skipping unsupported transport '%s' for media\n", handle->handle_id, rtransport);
				}
			} else if(!strcasecmp(rtype, "relay")) {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"]  Adding remote candidate component:%d stream:%d type:relay %s:%d --> %s:%d\n",
					handle->handle_id, rcomponent, stream->stream_id, rrelip, rrelport, rip, rport);
				/* We only support UDP/TCP/TLS... */
				if(strcasecmp(rtransport, "udp") && strcasecmp(rtransport, "tcp") && strcasecmp(rtransport, "tls")) {
					JANUS_LOG(LOG_VERB, "[%"SCNu64"]    Skipping unsupported transport '%s' for media\n", handle->handle_id, rtransport);
				} else {
					c = nice_candidate_new(NICE_CANDIDATE_TYPE_RELAYED);
				}
			} else {
				/* FIXME What now? */
				JANUS_LOG(LOG_ERR, "[%"SCNu64"]  Unknown remote candidate type:%s for component:%d stream:%d!\n",
					handle->handle_id, rtype, rcomponent, stream->stream_id);
			}
			if(c != NULL) {
				c->component_id = rcomponent;
				c->stream_id = stream->stream_id;
#ifndef HAVE_LIBNICE_TCP
				c->transport = NICE_CANDIDATE_TRANSPORT_UDP;
#else
				if(!strcasecmp(rtransport, "udp")) {
					JANUS_LOG(LOG_VERB, "[%"SCNu64"]  Transport: UDP\n", handle->handle_id);
					c->transport = NICE_CANDIDATE_TRANSPORT_UDP;
				} else {
					/* Check the type (https://tools.ietf.org/html/rfc6544#section-4.5) */
					const char *type = NULL;
					int ctype = 0;
					if(strstr(candidate, "tcptype active")) {
						type = "active";
						ctype = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE;
					} else if(strstr(candidate, "tcptype passive")) {
						type = "passive";
						ctype = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE;
					} else if(strstr(candidate, "tcptype so")) {
						type = "so";
						ctype = NICE_CANDIDATE_TRANSPORT_TCP_SO;
					} else {
						/* TODO: We should actually stop here... */
						JANUS_LOG(LOG_ERR, "[%"SCNu64"] Missing tcptype info for the TCP candidate!\n", handle->handle_id);
					}
					JANUS_LOG(LOG_VERB, "[%"SCNu64"]  Transport: TCP (%s)\n", handle->handle_id, type);
					c->transport = ctype;
				}
#endif
				strncpy(c->foundation, rfoundation, NICE_CANDIDATE_MAX_FOUNDATION);
				c->priority = rpriority;
				nice_address_set_from_string(&c->addr, rip);
				nice_address_set_port(&c->addr, rport);
				c->username = g_strdup(stream->ruser);
				c->password = g_strdup(stream->rpass);
				if(c->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || c->type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE) {
					nice_address_set_from_string(&c->base_addr, rrelip);
					nice_address_set_port(&c->base_addr, rrelport);
				} else if(c->type == NICE_CANDIDATE_TYPE_RELAYED) {
					/* FIXME Do we really need the base address for TURN? */
					nice_address_set_from_string(&c->base_addr, rrelip);
					nice_address_set_port(&c->base_addr, rrelport);
				}
				component->candidates = g_slist_append(component->candidates, c);
				JANUS_LOG(LOG_HUGE, "[%"SCNu64"]    Candidate added to the list! (%u elements for %d/%d)\n", handle->handle_id,
					g_slist_length(component->candidates), stream->stream_id, component->component_id);
				/* Save for the summary, in case we need it */
				component->remote_candidates = g_slist_append(component->remote_candidates, g_strdup(candidate));
				if(trickle) {
					if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_START)) {
						/* This is a trickle candidate and ICE has started, we should process it right away */
						if(!component->process_started) {
							/* Actually, ICE has JUST started for this component, take care of the candidates we've added so far */
							JANUS_LOG(LOG_INFO, "[%"SCNu64"] ICE already started for this component, setting candidates we have up to now\n", handle->handle_id);
							janus_ice_setup_remote_candidates(handle, component->stream_id, component->component_id);
						} else {
							GSList *candidates = NULL;
							candidates = g_slist_append(candidates, c);
							if(nice_agent_set_remote_candidates(handle->agent, stream->stream_id, component->component_id, candidates) < 1) {
								JANUS_LOG(LOG_ERR, "[%"SCNu64"] Failed to add trickle candidate :-(\n", handle->handle_id);
							} else {
								JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Trickle candidate added!\n", handle->handle_id);
							}
							g_slist_free(candidates);
						}
					} else {
						/* ICE hasn't started yet: to make sure we're not stuck, also check if we stopped processing the SDP */
						if(!janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_PROCESSING_OFFER)) {
							janus_flags_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_START);
							/* This is a trickle candidate and ICE has started, we should process it right away */
							if(!component->process_started) {
								/* Actually, ICE has JUST started for this component, take care of the candidates we've added so far */
								JANUS_LOG(LOG_INFO, "[%"SCNu64"] SDP processed but ICE not started yet for this component, setting candidates we have up to now\n", handle->handle_id);
								janus_ice_setup_remote_candidates(handle, component->stream_id, component->component_id);
							} else {
								GSList *candidates = NULL;
								candidates = g_slist_append(candidates, c);
								if(nice_agent_set_remote_candidates(handle->agent, stream->stream_id, component->component_id, candidates) < 1) {
									JANUS_LOG(LOG_ERR, "[%"SCNu64"] Failed to add trickle candidate :-(\n", handle->handle_id);
								} else {
									JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Trickle candidate added!\n", handle->handle_id);
								}
								g_slist_free(candidates);
							}
						} else {
							/* Still processing the offer/answer: queue the trickle candidate for now, we'll process it later */
							JANUS_LOG(LOG_VERB, "[%"SCNu64"] Queueing trickle candidate, status is not START yet\n", handle->handle_id);
						}
					}
				}
			}
		}
	} else {
		JANUS_LOG(LOG_ERR, "[%"SCNu64"] Failed to parse candidate (res=%d)...\n", handle->handle_id, res);
		janus_mutex_unlock(&handle->mutex);
		return res;
	}
	janus_mutex_unlock(&handle->mutex);
	return 0;
}
Beispiel #11
0
/* Parse SDP */
int janus_sdp_parse(janus_ice_handle *handle, janus_sdp *sdp) {
	if(!handle || !sdp)
		return -1;
	//~ sdp_parser_t *parser = (sdp_parser_t *)sdp->parser;
	//~ if(!parser)
		//~ return -1;
	sdp_session_t *remote_sdp = (sdp_session_t *)sdp->sdp;
	if(!remote_sdp)
		return -1;
	janus_ice_stream *stream = NULL;
	janus_ice_component *component = NULL;
	gchar *ruser = NULL, *rpass = NULL, *rhashing = NULL, *rfingerprint = NULL;
	int audio = 0, video = 0;
	gint rstream = 0;
	/* Ok, let's start */
	sdp_attribute_t *a = remote_sdp->sdp_attributes;
	while(a) {
		if(a->a_name) {
			if(!strcasecmp(a->a_name, "fingerprint")) {
				JANUS_PRINT("[%"SCNu64"] Fingerprint (global) : %s\n", handle->handle_id, a->a_value);
				if(strcasestr(a->a_value, "sha-256 ") == a->a_value) {
					rhashing = g_strdup("sha-256");
					rfingerprint = g_strdup(a->a_value + strlen("sha-256 "));
				} else if(strcasestr(a->a_value, "sha-1 ") == a->a_value) {
					JANUS_PRINT("[%"SCNu64"]  Hashing algorithm not the one we expected (sha-1 instead of sha-256), but that's ok\n", handle->handle_id);
					rhashing = g_strdup("sha-1");
					rfingerprint = g_strdup(a->a_value + strlen("sha-1 "));
				} else {
					/* FIXME We should handle this somehow anyway... OpenSSL supports them all */
					JANUS_PRINT("[%"SCNu64"]  Hashing algorithm not the one we expected (sha-256/sha-1), *NOT* cool\n", handle->handle_id);
				}
			} else if(!strcasecmp(a->a_name, "ice-ufrag")) {
				JANUS_PRINT("[%"SCNu64"] ICE ufrag (global):   %s\n", handle->handle_id, a->a_value);
				ruser = g_strdup(a->a_value);
			} else if(!strcasecmp(a->a_name, "ice-pwd")) {
				JANUS_PRINT("[%"SCNu64"] ICE pwd (global):     %s\n", handle->handle_id, a->a_value);
				rpass = g_strdup(a->a_value);
			}
		}
		a = a->a_next;
	}
	sdp_media_t *m = remote_sdp->sdp_media;
	while(m) {
		/* What media type is this? */
		if(m->m_type == sdp_media_audio) {
			audio++;
			if(audio > 1) {
				m = m->m_next;
				continue;
			}
			JANUS_PRINT("[%"SCNu64"] Parsing audio candidates (stream=%d)...\n", handle->handle_id, handle->audio_id);
			rstream = handle->audio_id;
			stream = g_hash_table_lookup(handle->streams, GUINT_TO_POINTER(handle->audio_id));
		} else if(m->m_type == sdp_media_video) {
			video++;
			if(video > 1) {
				m = m->m_next;
				continue;
			}
			JANUS_PRINT("[%"SCNu64"] Parsing video candidates (stream=%d)...\n", handle->handle_id, handle->video_id);
			rstream = handle->video_id;
			stream = g_hash_table_lookup(handle->streams, GUINT_TO_POINTER(handle->video_id));
		} else {
			JANUS_PRINT("[%"SCNu64"] Skipping unsupported media line...\n", handle->handle_id);
			m = m->m_next;
			continue;
		}
		/* Look for ICE credentials and fingerprint first: check media attributes */
		a = m->m_attributes;
		while(a) {
			if(a->a_name) {
				if(!strcasecmp(a->a_name, "fingerprint")) {
					JANUS_PRINT("[%"SCNu64"] Fingerprint (local) : %s\n", handle->handle_id, a->a_value);
					if(strcasestr(a->a_value, "sha-256 ") == a->a_value) {
						if(rhashing)
							g_free(rhashing);	/* FIXME We're overwriting the global one, if any */
						rhashing = g_strdup("sha-256");
						if(rfingerprint)
							g_free(rfingerprint);	/* FIXME We're overwriting the global one, if any */
						rfingerprint = g_strdup(a->a_value + strlen("sha-256 "));
					} else if(strcasestr(a->a_value, "sha-1 ") == a->a_value) {
						JANUS_PRINT("[%"SCNu64"]  Hashing algorithm not the one we expected (sha-1 instead of sha-256), but that's ok\n", handle->handle_id);
						if(rhashing)
							g_free(rhashing);	/* FIXME We're overwriting the global one, if any */
						rhashing = g_strdup("sha-1");
						if(rfingerprint)
							g_free(rfingerprint);	/* FIXME We're overwriting the global one, if any */
						rfingerprint = g_strdup(a->a_value + strlen("sha-1 "));
					} else {
						/* FIXME We should handle this somehow anyway... OpenSSL supports them all */
						JANUS_PRINT("[%"SCNu64"]  Hashing algorithm not the one we expected (sha-256), *NOT* cool\n", handle->handle_id);
					}
				} else if(!strcasecmp(a->a_name, "setup")) {
					JANUS_PRINT("[%"SCNu64"] DTLS setup (local):  %s\n", handle->handle_id, a->a_value);
					if(!strcasecmp(a->a_value, "actpass") || !strcasecmp(a->a_value, "passive"))
						stream->dtls_role = JANUS_DTLS_ROLE_CLIENT;
					else if(!strcasecmp(a->a_value, "active"))
						stream->dtls_role = JANUS_DTLS_ROLE_SERVER;
					/* TODO Handle holdconn... */
				} else if(!strcasecmp(a->a_name, "ice-ufrag")) {
					JANUS_PRINT("[%"SCNu64"] ICE ufrag (local):   %s\n", handle->handle_id, a->a_value);
					if(ruser)
						g_free(ruser);	/* FIXME We're overwriting the global one, if any */
					ruser = g_strdup(a->a_value);
				} else if(!strcasecmp(a->a_name, "ice-pwd")) {
					JANUS_PRINT("[%"SCNu64"] ICE pwd (local):     %s\n", handle->handle_id, a->a_value);
					if(rpass)
						g_free(rpass);	/* FIXME We're overwriting the global one, if any */
					rpass = g_strdup(a->a_value);
				}
			}
			a = a->a_next;
		}
		if(!ruser || !rpass || !rfingerprint || !rhashing) {
			/* Missing mandatory information, failure... */
			if(ruser)
				g_free(ruser);
			ruser = NULL;
			if(rpass)
				g_free(rpass);
			rpass = NULL;
			if(rhashing)
				g_free(rhashing);
			rhashing = NULL;
			if(rfingerprint)
				g_free(rfingerprint);
			rfingerprint = NULL;
			return -2;
		}
		handle->remote_hashing = g_strdup(rhashing);
		handle->remote_fingerprint = g_strdup(rfingerprint);
		/* Now look for candidates and codec info */
		a = m->m_attributes;
		while(a) {
			if(a->a_name) {
				if(!strcasecmp(a->a_name, "candidate")) {
					char rfoundation[32], rtransport[4], rip[24], rtype[6], rrelip[24];
					guint32 rcomponent, rpriority, rport, rrelport;
					int res = 0;
					if((res = sscanf(a->a_value, "%31s %30u %3s %30u %23s %30u typ %5s %*s %23s %*s %30u",
						rfoundation, &rcomponent, rtransport, &rpriority,
							rip, &rport, rtype, rrelip, &rrelport)) >= 7) {
						/* Add remote candidate */
						JANUS_PRINT("[%"SCNu64"] Adding remote candidate for component %d to stream %d\n", handle->handle_id, rcomponent, rstream);
						component = g_hash_table_lookup(stream->components, GUINT_TO_POINTER(rcomponent));
						if(component == NULL) {
							JANUS_DEBUG("[%"SCNu64"] No such component %d in stream %d?\n", handle->handle_id, rcomponent, rstream);
						} else {
							component->component_id = rcomponent;
							component->stream_id = rstream;
							NiceCandidate *c = NULL;
							if(!strcasecmp(rtype, "host")) {
								JANUS_PRINT("[%"SCNu64"]  Adding host candidate... %s:%d\n", handle->handle_id, rip, rport);
								/* We only support UDP... */
								if(strcasecmp(rtransport, "udp")) {
									JANUS_DEBUG("[%"SCNu64"]    Unsupported transport %s!\n", handle->handle_id, rtransport);
								} else {
									c = nice_candidate_new(NICE_CANDIDATE_TYPE_HOST);
								}
							} else if(!strcasecmp(rtype, "srflx")) {
								JANUS_PRINT("[%"SCNu64"]  Adding srflx candidate... %s:%d --> %s:%d \n", handle->handle_id, rrelip, rrelport, rip, rport);
								/* We only support UDP... */
								if(strcasecmp(rtransport, "udp")) {
									JANUS_DEBUG("[%"SCNu64"]    Unsupported transport %s!\n", handle->handle_id, rtransport);
								}else {
									c = nice_candidate_new(NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE);
								}
							} else if(!strcasecmp(rtype, "prflx")) {
								JANUS_PRINT("[%"SCNu64"]  Adding prflx candidate... %s:%d --> %s:%d\n", handle->handle_id, rrelip, rrelport, rip, rport);
								/* We only support UDP... */
								if(strcasecmp(rtransport, "udp")) {
									JANUS_DEBUG("[%"SCNu64"]    Unsupported transport %s!\n", handle->handle_id, rtransport);
								} else {
									c = nice_candidate_new(NICE_CANDIDATE_TYPE_PEER_REFLEXIVE);
								}
							} else if(!strcasecmp(rtype, "relay")) {
								JANUS_PRINT("[%"SCNu64"]  Adding relay candidate... %s:%d --> %s:%d\n", handle->handle_id, rrelip, rrelport, rip, rport);
								/* We only support UDP/TCP/TLS... */
								if(strcasecmp(rtransport, "udp") && strcasecmp(rtransport, "tcp") && strcasecmp(rtransport, "tls")) {
									JANUS_DEBUG("[%"SCNu64"]    Unsupported transport %s!\n", handle->handle_id, rtransport);
								} else {
									c = nice_candidate_new(NICE_CANDIDATE_TYPE_RELAYED);
								}
							} else {
								/* FIXME What now? */
								JANUS_DEBUG("[%"SCNu64"]  Unknown candidate type %s!\n", handle->handle_id, rtype);
							}
							if(c != NULL) {
								c->component_id = rcomponent;
								c->stream_id = rstream;
								c->transport = NICE_CANDIDATE_TRANSPORT_UDP;
								strncpy(c->foundation, rfoundation, NICE_CANDIDATE_MAX_FOUNDATION);
								c->priority = rpriority;
								nice_address_set_from_string(&c->addr, rip);
								nice_address_set_port(&c->addr, rport);
								c->username = g_strdup(ruser);
								c->password = g_strdup(rpass);
								if(c->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || c->type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE) {
									nice_address_set_from_string(&c->base_addr, rrelip);
									nice_address_set_port(&c->base_addr, rrelport);
								} else if(c->type == NICE_CANDIDATE_TYPE_RELAYED) {
									/* FIXME Do we really need the base address for TURN? */
									nice_address_set_from_string(&c->base_addr, rrelip);
									nice_address_set_port(&c->base_addr, rrelport);
								}
								component->candidates = g_slist_append(component->candidates, c);
								JANUS_PRINT("[%"SCNu64"]    Candidate added to the list! (%u elements for %d/%d)\n", handle->handle_id,
									g_slist_length(component->candidates), stream->stream_id, component->component_id);
							}
						}
					} else {
						JANUS_DEBUG("[%"SCNu64"] Failed to parse candidate... (%d)\n", handle->handle_id, res);
					}
				}
			}
			a = a->a_next;
		}
		m = m->m_next;
	}
	if(ruser)
		g_free(ruser);
	ruser = NULL;
	if(rpass)
		g_free(rpass);
	rpass = NULL;
	if(rhashing)
		g_free(rhashing);
	rhashing = NULL;
	if(rfingerprint)
		g_free(rfingerprint);
	rfingerprint = NULL;
	return 0;	/* FIXME Handle errors better */
}
Beispiel #12
0
  bool NiceConnection::setRemoteCandidates(std::vector<CandidateInfo> &candidates, bool isBundle) {
    if(agent_==NULL){
      running_=false;
      return false;
    }
    GSList* candList = NULL;
    ELOG_DEBUG("Setting remote candidates %lu, mediatype %d", candidates.size(), this->mediaType);

    for (unsigned int it = 0; it < candidates.size(); it++) {
      NiceCandidateType nice_cand_type;
      CandidateInfo cinfo = candidates[it];
      //If bundle we will add the candidates regardless the mediaType
      if (cinfo.componentId !=1 || (!isBundle && cinfo.mediaType!=this->mediaType ))
        continue;

      switch (cinfo.hostType) {
        case HOST:
          nice_cand_type = NICE_CANDIDATE_TYPE_HOST;
          break;
        case SRFLX:
          nice_cand_type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE;
          break;
        case PRFLX:
          nice_cand_type = NICE_CANDIDATE_TYPE_PEER_REFLEXIVE;
          break;
        case RELAY:
          nice_cand_type = NICE_CANDIDATE_TYPE_RELAYED;
          break;
        default:
          nice_cand_type = NICE_CANDIDATE_TYPE_HOST;
          break;
      }
      NiceCandidate* thecandidate = nice_candidate_new(nice_cand_type);
      thecandidate->username = strdup(cinfo.username.c_str());
      thecandidate->password = strdup(cinfo.password.c_str());
      thecandidate->stream_id = (guint) 1;
      thecandidate->component_id = cinfo.componentId;
      thecandidate->priority = cinfo.priority;
      thecandidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
      nice_address_set_from_string(&thecandidate->addr, cinfo.hostAddress.c_str());
      nice_address_set_port(&thecandidate->addr, cinfo.hostPort);
      
      if (cinfo.hostType == RELAY||cinfo.hostType==SRFLX){
        nice_address_set_from_string(&thecandidate->base_addr, cinfo.rAddress.c_str());
        nice_address_set_port(&thecandidate->base_addr, cinfo.rPort);
        ELOG_DEBUG("Adding remote candidate type %d addr %s port %d raddr %s rport %d", cinfo.hostType, cinfo.hostAddress.c_str(), cinfo.hostPort,
            cinfo.rAddress.c_str(), cinfo.rPort);
      }else{
        ELOG_DEBUG("Adding remote candidate type %d addr %s port %d priority %d componentId %d, username %s, pass %s", 
          cinfo.hostType, 
          cinfo.hostAddress.c_str(), 
          cinfo.hostPort, 
          cinfo.priority, 
          cinfo.componentId,
          cinfo.username.c_str(),
          cinfo.password.c_str()
          );
      }
      candList = g_slist_prepend(candList, thecandidate);
    }
    //TODO: Set Component Id properly, now fixed at 1 
    nice_agent_set_remote_candidates(agent_, (guint) 1, 1, candList);
    g_slist_free_full(candList, (GDestroyNotify)&nice_candidate_free);
    
    return true;
  }
Beispiel #13
0
/*
 * Adds a new peer reflexive candidate to the list of known
 * remote candidates. The candidate is however not paired with
 * existing local candidates.
 *
 * See ICE sect 7.2.1.3 "Learning Peer Reflexive Candidates" (ID-19).
 *
 * @return pointer to the created candidate, or NULL on error
 */
NiceCandidate *discovery_learn_remote_peer_reflexive_candidate (
  NiceAgent *agent,
  NiceStream *stream,
  NiceComponent *component,
  guint32 priority,
  const NiceAddress *remote_address,
  NiceSocket *nicesock,
  NiceCandidate *local,
  NiceCandidate *remote)
{
  NiceCandidate *candidate;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_PEER_REFLEXIVE);

  candidate->addr = *remote_address;
  candidate->base_addr = *remote_address;
  if (remote)
    candidate->transport = remote->transport;
  else if (local)
    candidate->transport = conn_check_match_transport (local->transport);
  else {
    if (nicesock->type == NICE_SOCKET_TYPE_UDP_BSD ||
        nicesock->type == NICE_SOCKET_TYPE_UDP_TURN)
      candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
    else
      candidate->transport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE;
  }
  candidate->sockptr = nicesock;
  candidate->stream_id = stream->id;
  candidate->component_id = component->id;

  /* if the check didn't contain the PRIORITY attribute, then the priority will
   * be 0, which is invalid... */
  if (priority != 0) {
    candidate->priority = priority;
  } else if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, FALSE);
  } else {
    candidate->priority = nice_candidate_ice_priority (candidate,
        agent->reliable, FALSE);
  }

  priv_assign_remote_foundation (agent, candidate);

  if ((agent->compatibility == NICE_COMPATIBILITY_MSN ||
       agent->compatibility == NICE_COMPATIBILITY_OC2007) &&
      remote && local) {
    guchar *new_username = NULL;
    guchar *decoded_local = NULL;
    guchar *decoded_remote = NULL;
    gsize local_size;
    gsize remote_size;
    g_free(candidate->username);
    g_free (candidate->password);

    decoded_local = g_base64_decode (local->username, &local_size);
    decoded_remote = g_base64_decode (remote->username, &remote_size);

    new_username = g_new0(guchar, local_size + remote_size);
    memcpy(new_username, decoded_remote, remote_size);
    memcpy(new_username + remote_size, decoded_local, local_size);

    candidate->username = g_base64_encode (new_username, local_size + remote_size);
    g_free(new_username);
    g_free(decoded_local);
    g_free(decoded_remote);

    candidate->password = g_strdup(remote->password);
  } else if (remote) {
    g_free (candidate->username);
    g_free (candidate->password);
    candidate->username = g_strdup(remote->username);
    candidate->password = g_strdup(remote->password);
  }

  /* note: candidate username and password are left NULL as stream 
     level ufrag/password are used */

  component->remote_candidates = g_slist_append (component->remote_candidates,
      candidate);

  agent_signal_new_remote_candidate (agent, candidate);

  return candidate;
}
Beispiel #14
0
/*
 * Creates a peer reflexive candidate for 'component_id' of stream
 * 'stream_id'.
 *
 * @return pointer to the created candidate, or NULL on error
 */
NiceCandidate*
discovery_add_peer_reflexive_candidate (
  NiceAgent *agent,
  guint stream_id,
  guint component_id,
  NiceAddress *address,
  NiceSocket *base_socket,
  NiceCandidate *local,
  NiceCandidate *remote)
{
  NiceCandidate *candidate;
  NiceComponent *component;
  NiceStream *stream;
  gboolean result;

  if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
    return NULL;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_PEER_REFLEXIVE);
  if (local)
    candidate->transport = local->transport;
  else if (remote)
    candidate->transport = conn_check_match_transport (remote->transport);
  else {
    if (base_socket->type == NICE_SOCKET_TYPE_UDP_BSD ||
        base_socket->type == NICE_SOCKET_TYPE_UDP_TURN)
      candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
    else
      candidate->transport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE;
  }
  candidate->stream_id = stream_id;
  candidate->component_id = component_id;
  candidate->addr = *address;
  candidate->sockptr = base_socket;
  candidate->base_addr = base_socket->addr;

  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, FALSE);
  } else {
    candidate->priority = nice_candidate_ice_priority (candidate,
        agent->reliable, FALSE);
  }

  candidate->priority = ensure_unique_priority (component,
      candidate->priority);
  priv_assign_foundation (agent, candidate);

  if ((agent->compatibility == NICE_COMPATIBILITY_MSN ||
       agent->compatibility == NICE_COMPATIBILITY_OC2007) &&
      remote && local) {
    guchar *new_username = NULL;
    guchar *decoded_local = NULL;
    guchar *decoded_remote = NULL;
    gsize local_size;
    gsize remote_size;
    g_free(candidate->username);
    g_free(candidate->password);

    decoded_local = g_base64_decode (local->username, &local_size);
    decoded_remote = g_base64_decode (remote->username, &remote_size);

    new_username = g_new0(guchar, local_size + remote_size);
    memcpy(new_username, decoded_local, local_size);
    memcpy(new_username + local_size, decoded_remote, remote_size);

    candidate->username = g_base64_encode (new_username, local_size + remote_size);
    g_free(new_username);
    g_free(decoded_local);
    g_free(decoded_remote);

    candidate->password = g_strdup(local->password);
  } else if (local) {
    g_free(candidate->username);
    g_free(candidate->password);

    candidate->username = g_strdup(local->username);
    candidate->password = g_strdup(local->password);
  }

  result = priv_add_local_candidate_pruned (agent, stream_id, component, candidate);
  if (result != TRUE) {
    /* error: memory allocation, or duplicate candidate */
    nice_candidate_free (candidate), candidate = NULL;
  }

  return candidate;
}
Beispiel #15
0
/*
 * Creates a server reflexive candidate for 'component_id' of stream
 * 'stream_id'.
 *
 * @return pointer to the created candidate, or NULL on error
 */
NiceCandidate*
discovery_add_relay_candidate (
  NiceAgent *agent,
  guint stream_id,
  guint component_id,
  NiceAddress *address,
  NiceCandidateTransport transport,
  NiceSocket *base_socket,
  TurnServer *turn)
{
  NiceCandidate *candidate;
  NiceComponent *component;
  NiceStream *stream;
  NiceSocket *relay_socket = NULL;

  if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
    return NULL;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_RELAYED);
  candidate->transport = transport;
  candidate->stream_id = stream_id;
  candidate->component_id = component_id;
  candidate->addr = *address;
  candidate->turn = turn_server_ref (turn);

  /* step: link to the base candidate+socket */
  relay_socket = nice_udp_turn_socket_new (agent->main_context, address,
      base_socket, &turn->server,
      turn->username, turn->password,
      agent_to_turn_socket_compatibility (agent));
  if (!relay_socket)
    goto errors;

  candidate->sockptr = relay_socket;
  candidate->base_addr = base_socket->addr;

  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, FALSE);
  } else {
    candidate->priority =  nice_candidate_ice_priority (candidate,
        agent->reliable, FALSE);
  }

  candidate->priority = ensure_unique_priority (component,
      candidate->priority);
  priv_generate_candidate_credentials (agent, candidate);

  /* Google uses the turn username as the candidate username */
  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    g_free (candidate->username);
    candidate->username = g_strdup (turn->username);
  }

  priv_assign_foundation (agent, candidate);

  if (!priv_add_local_candidate_pruned (agent, stream_id, component, candidate))
    goto errors;

  nice_component_attach_socket (component, relay_socket);
  agent_signal_new_candidate (agent, candidate);

  return candidate;

errors:
  nice_candidate_free (candidate);
  if (relay_socket)
    nice_socket_free (relay_socket);
  return NULL;
}
Beispiel #16
0
/*
 * Creates a local host candidate for 'component_id' of stream
 * 'stream_id'.
 *
 * @return pointer to the created candidate, or NULL on error
 */
HostCandidateResult discovery_add_local_host_candidate (
  NiceAgent *agent,
  guint stream_id,
  guint component_id,
  NiceAddress *address,
  NiceCandidateTransport transport,
  NiceCandidate **outcandidate)
{
  NiceCandidate *candidate;
  NiceComponent *component;
  NiceStream *stream;
  NiceSocket *nicesock = NULL;
  HostCandidateResult res = HOST_CANDIDATE_FAILED;

  if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
    return res;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST);
  candidate->transport = transport;
  candidate->stream_id = stream_id;
  candidate->component_id = component_id;
  candidate->addr = *address;
  candidate->base_addr = *address;
  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, FALSE);
  } else {
    candidate->priority = nice_candidate_ice_priority (candidate,
        agent->reliable, FALSE);
  }

  candidate->priority = ensure_unique_priority (component,
      candidate->priority);
  priv_generate_candidate_credentials (agent, candidate);
  priv_assign_foundation (agent, candidate);

  /* note: candidate username and password are left NULL as stream
     level ufrag/password are used */
  if (transport == NICE_CANDIDATE_TRANSPORT_UDP) {
    nicesock = nice_udp_bsd_socket_new (address);
  } else if (transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE) {
    nicesock = nice_tcp_active_socket_new (agent->main_context, address);
  } else if (transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) {
    nicesock = nice_tcp_passive_socket_new (agent->main_context, address);
  } else {
    /* TODO: Add TCP-SO */
  }
  if (!nicesock) {
    res = HOST_CANDIDATE_CANT_CREATE_SOCKET;
    goto errors;
  }

  candidate->sockptr = nicesock;
  candidate->addr = nicesock->addr;
  candidate->base_addr = nicesock->addr;

  if (!priv_add_local_candidate_pruned (agent, stream_id, component,
          candidate)) {
    res = HOST_CANDIDATE_REDUNDANT;
    goto errors;
  }

  _priv_set_socket_tos (agent, nicesock, stream->tos);
  nice_component_attach_socket (component, nicesock);

  *outcandidate = candidate;

  return HOST_CANDIDATE_SUCCESS;

errors:
  nice_candidate_free (candidate);
  if (nicesock)
    nice_socket_free (nicesock);
  return res;
}