~ubuntu-branches/ubuntu/raring/libnice/raring

« back to all changes in this revision

Viewing changes to agent/agent.c

  • Committer: robert.ancell at canonical
  • Date: 2011-02-07 04:17:01 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: robert.ancell@canonical.com-20110207041701-psaqkjc1v3it3ttk
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
149
149
      STUN_USAGE_ICE_COMPATIBILITY_GOOGLE :
150
150
      agent->compatibility == NICE_COMPATIBILITY_MSN ?
151
151
      STUN_USAGE_ICE_COMPATIBILITY_MSN :
 
152
      agent->compatibility == NICE_COMPATIBILITY_WLM2009 ?
 
153
      STUN_USAGE_ICE_COMPATIBILITY_WLM2009 :
 
154
      agent->compatibility == NICE_COMPATIBILITY_OC2007 ?
 
155
      STUN_USAGE_ICE_COMPATIBILITY_MSN :
 
156
      agent->compatibility == NICE_COMPATIBILITY_OC2007R2 ?
 
157
      STUN_USAGE_ICE_COMPATIBILITY_WLM2009 :
152
158
      STUN_USAGE_ICE_COMPATIBILITY_RFC5245;
153
159
}
154
160
 
161
167
      agent->compatibility == NICE_COMPATIBILITY_MSN ?
162
168
      STUN_USAGE_TURN_COMPATIBILITY_MSN :
163
169
      agent->compatibility == NICE_COMPATIBILITY_WLM2009 ?
164
 
      STUN_USAGE_TURN_COMPATIBILITY_MSN : STUN_USAGE_TURN_COMPATIBILITY_DRAFT9;
 
170
      STUN_USAGE_TURN_COMPATIBILITY_MSN :
 
171
      agent->compatibility == NICE_COMPATIBILITY_OC2007 ?
 
172
      STUN_USAGE_TURN_COMPATIBILITY_OC2007 :
 
173
      agent->compatibility == NICE_COMPATIBILITY_OC2007R2 ?
 
174
      STUN_USAGE_TURN_COMPATIBILITY_OC2007 :
 
175
      STUN_USAGE_TURN_COMPATIBILITY_RFC5766;
165
176
}
166
177
 
167
178
NiceTurnSocketCompatibility
173
184
      NICE_TURN_SOCKET_COMPATIBILITY_MSN :
174
185
      agent->compatibility == NICE_COMPATIBILITY_WLM2009 ?
175
186
      NICE_TURN_SOCKET_COMPATIBILITY_MSN :
176
 
      NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9;
 
187
      agent->compatibility == NICE_COMPATIBILITY_OC2007 ?
 
188
      NICE_TURN_SOCKET_COMPATIBILITY_OC2007 :
 
189
      agent->compatibility == NICE_COMPATIBILITY_OC2007R2 ?
 
190
      NICE_TURN_SOCKET_COMPATIBILITY_OC2007 :
 
191
      NICE_TURN_SOCKET_COMPATIBILITY_RFC5766;
177
192
}
178
193
 
179
194
Stream *agent_find_stream (NiceAgent *agent, guint stream_id)
283
298
  g_object_class_install_property (gobject_class, PROP_STUN_SERVER,
284
299
      g_param_spec_string (
285
300
        "stun-server",
286
 
        "STUN server",
287
 
        "The STUN server used to obtain server-reflexive candidates",
 
301
        "STUN server IP address",
 
302
        "The IP address (not the hostname) of the STUN server to use",
288
303
        NULL,
289
304
        G_PARAM_READWRITE));
290
305
 
292
307
      g_param_spec_uint (
293
308
        "stun-server-port",
294
309
        "STUN server port",
295
 
        "The STUN server used to obtain server-reflexive candidates",
 
310
        "Port of the STUN server used to gather server-reflexive candidates",
296
311
        1, 65536,
297
312
        1, /* not a construct property, ignored */
298
313
        G_PARAM_READWRITE));
840
855
            STUN_COMPATIBILITY_WLM2009,
841
856
            STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
842
857
            STUN_AGENT_USAGE_USE_FINGERPRINT);
 
858
      } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007) {
 
859
        stun_agent_init (&agent->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES,
 
860
            STUN_COMPATIBILITY_RFC3489,
 
861
            STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
 
862
            STUN_AGENT_USAGE_FORCE_VALIDATER |
 
863
            STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES);
 
864
      } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
 
865
        stun_agent_init (&agent->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES,
 
866
            STUN_COMPATIBILITY_WLM2009,
 
867
            STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
 
868
            STUN_AGENT_USAGE_USE_FINGERPRINT |
 
869
            STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES);
843
870
      } else {
844
871
        stun_agent_init (&agent->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES,
845
872
            STUN_COMPATIBILITY_RFC5389,
851
878
      break;
852
879
 
853
880
    case PROP_STUN_SERVER:
 
881
      g_free (agent->stun_server_ip);
854
882
      agent->stun_server_ip = g_value_dup_string (value);
855
883
      break;
856
884
 
875
903
      break;
876
904
 
877
905
    case PROP_PROXY_IP:
 
906
      g_free (agent->proxy_ip);
878
907
      agent->proxy_ip = g_value_dup_string (value);
879
908
      break;
880
909
 
887
916
      break;
888
917
 
889
918
    case PROP_PROXY_USERNAME:
 
919
      g_free (agent->proxy_username);
890
920
      agent->proxy_username = g_value_dup_string (value);
891
921
      break;
892
922
 
893
923
    case PROP_PROXY_PASSWORD:
 
924
      g_free (agent->proxy_password);
894
925
      agent->proxy_password = g_value_dup_string (value);
895
926
      break;
896
927
 
1057
1088
    const gchar *buffer, guint32 len, gpointer user_data)
1058
1089
{
1059
1090
  TcpUserData *data = (TcpUserData *)user_data;
1060
 
  NiceAgent *agent = data->agent;
1061
1091
  Component *component = data->component;
1062
 
  Stream *stream = data->stream;
1063
1092
 
1064
1093
  if (component->selected_pair.local != NULL) {
1065
1094
    NiceSocket *sock;
1069
1098
    gchar tmpbuf[INET6_ADDRSTRLEN];
1070
1099
    nice_address_to_string (&component->selected_pair.remote->addr, tmpbuf);
1071
1100
 
1072
 
    nice_debug ("Agent %p : s%d:%d: sending %d bytes to [%s]:%d", agent,
1073
 
        stream->id, component->id, len, tmpbuf,
 
1101
    nice_debug ("Agent %p : s%d:%d: sending %d bytes to [%s]:%d", data->agent,
 
1102
        data->stream->id, component->id, len, tmpbuf,
1074
1103
        nice_address_get_port (&component->selected_pair.remote->addr));
1075
1104
#endif
1076
1105
 
1313
1342
  cdisco->component = stream_find_component_by_id (stream, component_id);
1314
1343
  cdisco->agent = agent;
1315
1344
  stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES,
1316
 
      STUN_COMPATIBILITY_RFC3489, 0);
 
1345
      STUN_COMPATIBILITY_RFC3489,
 
1346
      (agent->compatibility == NICE_COMPATIBILITY_OC2007 ||
 
1347
       agent->compatibility == NICE_COMPATIBILITY_OC2007R2) ?
 
1348
        STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES : 0);
1317
1349
 
1318
1350
  nice_debug ("Agent %p : Adding new srv-rflx candidate discovery %p\n",
1319
1351
      agent, cdisco);
1410
1442
    stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES,
1411
1443
        STUN_COMPATIBILITY_RFC3489,
1412
1444
        STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS);
 
1445
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007 ||
 
1446
      agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
 
1447
    stun_agent_init (&cdisco->stun_agent, STUN_MSOC_KNOWN_ATTRIBUTES,
 
1448
        STUN_COMPATIBILITY_OC2007,
 
1449
        STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS |
 
1450
        STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES);
1413
1451
  } else {
1414
1452
    stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES,
1415
1453
        STUN_COMPATIBILITY_RFC5389,
1488
1526
  g_return_val_if_fail (server_port, FALSE);
1489
1527
  g_return_val_if_fail (username, FALSE);
1490
1528
  g_return_val_if_fail (password, FALSE);
1491
 
  g_return_val_if_fail (type <= NICE_PROXY_TYPE_LAST, FALSE);
 
1529
  g_return_val_if_fail (type <= NICE_RELAY_TYPE_TURN_TLS, FALSE);
1492
1530
 
1493
1531
  agent_lock();
1494
1532
 
1566
1604
 
1567
1605
  agent_lock();
1568
1606
 
1569
 
  nice_debug ("Agent %p : Sucessfully mapped %s:%d to %s:%d", agent, local_ip,
 
1607
  nice_debug ("Agent %p : Successfully mapped %s:%d to %s:%d", agent, local_ip,
1570
1608
      local_port, external_ip, external_port);
1571
1609
 
1572
1610
  if (!nice_address_set_from_string (&localaddr, local_ip))
1666
1704
  guint n;
1667
1705
  GSList *i;
1668
1706
  Stream *stream;
 
1707
  GSList *local_addresses = NULL;
 
1708
  gboolean ret = TRUE;
1669
1709
 
1670
1710
  agent_lock();
1671
1711
 
1672
1712
  stream = agent_find_stream (agent, stream_id);
1673
1713
  if (stream == NULL) {
1674
 
    goto done;
 
1714
    agent_unlock();
 
1715
    return FALSE;
1675
1716
  }
1676
1717
 
1677
1718
  nice_debug ("Agent %p : In %s mode, starting candidate gathering.", agent,
1710
1751
      NiceAddress *addr = nice_address_new ();
1711
1752
 
1712
1753
      if (nice_address_set_from_string (addr, item->data)) {
1713
 
        nice_agent_add_local_address (agent, addr);
 
1754
        local_addresses = g_slist_append (local_addresses, addr);
 
1755
      } else {
 
1756
        nice_address_free (addr);
1714
1757
      }
1715
 
      nice_address_free (addr);
1716
1758
    }
1717
1759
 
1718
1760
    g_list_foreach (addresses, (GFunc) g_free, NULL);
1719
1761
    g_list_free (addresses);
 
1762
  } else {
 
1763
    for (i = agent->local_addresses; i; i = i->next) {
 
1764
      NiceAddress *addr = i->data;
 
1765
      NiceAddress *dup = nice_address_dup (addr);
 
1766
 
 
1767
      local_addresses = g_slist_append (local_addresses, dup);
 
1768
    }
1720
1769
  }
1721
1770
 
1722
1771
  /* generate a local host candidate for each local address */
1723
 
  for (i = agent->local_addresses; i; i = i->next){
 
1772
  for (i = local_addresses; i; i = i->next) {
1724
1773
    NiceAddress *addr = i->data;
1725
1774
    NiceCandidate *host_candidate;
1726
1775
 
1731
1780
 
1732
1781
    for (n = 0; n < stream->n_components; n++) {
1733
1782
      Component *component = stream_find_component_by_id (stream, n + 1);
 
1783
      guint current_port = component->min_port;
1734
1784
 
1735
1785
      if (agent->reliable && component->tcp == NULL) {
1736
1786
        nice_debug ("Agent %p: not gathering candidates for s%d:%d because "
1739
1789
        continue;
1740
1790
      }
1741
1791
 
1742
 
      host_candidate = discovery_add_local_host_candidate (agent, stream->id,
1743
 
          n + 1, addr);
 
1792
      host_candidate = NULL;
 
1793
      while (host_candidate == NULL) {
 
1794
        nice_debug ("Agent %p: Trying to create host candidate on port %d", agent, current_port);
 
1795
        nice_address_set_port (addr, current_port);
 
1796
        host_candidate = discovery_add_local_host_candidate (agent, stream->id,
 
1797
            n + 1, addr);
 
1798
        if (current_port > 0)
 
1799
          current_port++;
 
1800
        if (current_port == 0 || current_port > component->max_port)
 
1801
          break;
 
1802
      }
 
1803
      nice_address_set_port (addr, 0);
1744
1804
 
1745
1805
      if (!host_candidate) {
1746
 
        g_warning ("No host candidate??");
1747
 
        return FALSE;
 
1806
        gchar ip[NICE_ADDRESS_STRING_LEN];
 
1807
        nice_address_to_string (addr, ip);
 
1808
        nice_debug ("Agent %p: Unable to add local host candidate %s for s%d:%d"
 
1809
            ". Invalid interface?", agent, ip, stream->id, component->id);
 
1810
        ret = FALSE;
 
1811
        goto error;
1748
1812
      }
1749
1813
 
1750
1814
#ifdef HAVE_GUPNP
1792
1856
  stream->gathering = TRUE;
1793
1857
 
1794
1858
 
 
1859
  /* Only signal the new candidates after we're sure that the gathering was
 
1860
   * succesfful. But before sending gathering-done */
 
1861
  for (n = 0; n < stream->n_components; n++) {
 
1862
    Component *component = stream_find_component_by_id (stream, n + 1);
 
1863
    for (i = component->local_candidates; i; i = i->next) {
 
1864
      NiceCandidate *candidate = i->data;
 
1865
      agent_signal_new_candidate (agent, candidate);
 
1866
    }
 
1867
  }
 
1868
 
1795
1869
  /* note: no async discoveries pending, signal that we are ready */
1796
1870
  if (agent->discovery_unsched_items == 0) {
1797
1871
    nice_debug ("Agent %p: Candidate gathering FINISHED, no scheduled items.",
1802
1876
    discovery_schedule (agent);
1803
1877
  }
1804
1878
 
1805
 
 done:
 
1879
 error:
 
1880
  for (i = local_addresses; i; i = i->next)
 
1881
    nice_address_free (i->data);
 
1882
  g_slist_free (local_addresses);
 
1883
 
 
1884
  if (ret == FALSE) {
 
1885
    priv_free_upnp (agent);
 
1886
    for (n = 0; n < stream->n_components; n++) {
 
1887
      Component *component = stream_find_component_by_id (stream, n + 1);
 
1888
 
 
1889
      priv_detach_stream_component (stream, component);
 
1890
 
 
1891
      for (i = component->local_candidates; i; i = i->next) {
 
1892
        NiceCandidate *candidate = i->data;
 
1893
        nice_candidate_free (candidate);
 
1894
      }
 
1895
      for (i = component->sockets; i; i = i->next) {
 
1896
        NiceSocket *udpsocket = i->data;
 
1897
        nice_socket_free (udpsocket);
 
1898
      }
 
1899
      g_slist_free (component->local_candidates);
 
1900
      component->local_candidates = NULL;
 
1901
      g_slist_free (component->sockets);
 
1902
      component->sockets = NULL;
 
1903
    }
 
1904
    discovery_prune_stream (agent, stream_id);
 
1905
  }
1806
1906
 
1807
1907
  agent_unlock();
1808
1908
 
1809
 
  return TRUE;
 
1909
  return ret;
1810
1910
}
1811
1911
 
1812
1912
static void priv_free_upnp (NiceAgent *agent)
1875
1975
  agent_unlock();
1876
1976
}
1877
1977
 
 
1978
NICEAPI_EXPORT void
 
1979
nice_agent_set_port_range (NiceAgent *agent, guint stream_id, guint component_id,
 
1980
    guint min_port, guint max_port)
 
1981
{
 
1982
  Component *component;
 
1983
 
 
1984
  agent_lock();
 
1985
 
 
1986
  if (agent_find_component (agent, stream_id, component_id, NULL, &component)) {
 
1987
    component->min_port = min_port;
 
1988
    component->max_port = max_port;
 
1989
  }
 
1990
 
 
1991
  agent_unlock();
 
1992
}
 
1993
 
1878
1994
NICEAPI_EXPORT gboolean
1879
1995
nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr)
1880
1996
{
2181
2297
 
2182
2298
  agent->media_after_tick = TRUE;
2183
2299
 
2184
 
  if (stun_message_validate_buffer_length ((uint8_t *) buf, (size_t) len) != len)
 
2300
  if (stun_message_validate_buffer_length ((uint8_t *) buf, (size_t) len,
 
2301
      (agent->compatibility != NICE_COMPATIBILITY_OC2007 &&
 
2302
       agent->compatibility != NICE_COMPATIBILITY_OC2007R2)) != len)
2185
2303
    /* If the retval is no 0, its not a valid stun packet, probably data */
2186
2304
    return len;
2187
2305
 
2372
2490
  g_free (agent->stun_server_ip);
2373
2491
  agent->stun_server_ip = NULL;
2374
2492
 
 
2493
  g_free (agent->proxy_ip);
 
2494
  agent->proxy_ip = NULL;
 
2495
  g_free (agent->proxy_username);
 
2496
  agent->proxy_username = NULL;
 
2497
  g_free (agent->proxy_password);
 
2498
  agent->proxy_password = NULL;
 
2499
 
2375
2500
  nice_rng_free (agent->rng);
2376
2501
  agent->rng = NULL;
2377
2502