patch from issue 25469004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7517 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/app/webrtc/webrtcsdp.cc b/talk/app/webrtc/webrtcsdp.cc
index 5887409..daba5d8 100644
--- a/talk/app/webrtc/webrtcsdp.cc
+++ b/talk/app/webrtc/webrtcsdp.cc
@@ -197,13 +197,17 @@
 static const char kTimeDescription[] = "t=0 0";
 static const char kAttrGroup[] = "a=group:BUNDLE";
 static const char kConnectionNettype[] = "IN";
-static const char kConnectionAddrtype[] = "IP4";
+static const char kConnectionIpv4Addrtype[] = "IP4";
+static const char kConnectionIpv6Addrtype[] = "IP6";
 static const char kMediaTypeVideo[] = "video";
 static const char kMediaTypeAudio[] = "audio";
 static const char kMediaTypeData[] = "application";
 static const char kMediaPortRejected[] = "0";
-static const char kDefaultAddress[] = "0.0.0.0";
-static const char kDefaultPort[] = "1";
+// draft-ietf-mmusic-trickle-ice-01
+// When no candidates have been gathered, set the connection
+// address to IP6 ::.
+static const char kDummyAddress[] = "::";
+static const char kDummyPort[] = "9";
 // RFC 3556
 static const char kApplicationSpecificMaximum[] = "AS";
 
@@ -667,10 +671,13 @@
 // The value of |component_id| currently supported are 1 (RTP) and 2 (RTCP).
 // TODO: Decide the default destination in webrtcsession and
 // pass it down via SessionDescription.
-static bool GetDefaultDestination(const std::vector<Candidate>& candidates,
-    int component_id, std::string* port, std::string* ip) {
-  *port = kDefaultPort;
-  *ip = kDefaultAddress;
+static void GetDefaultDestination(
+    const std::vector<Candidate>& candidates,
+    int component_id, std::string* port,
+    std::string* ip, std::string* addr_type) {
+  *addr_type = kConnectionIpv6Addrtype;
+  *port = kDummyPort;
+  *ip = kDummyAddress;
   int current_preference = kPreferenceUnknown;
   for (std::vector<Candidate>::const_iterator it = candidates.begin();
        it != candidates.end(); ++it) {
@@ -685,8 +692,13 @@
     current_preference = preference;
     *port = it->address().PortAsString();
     *ip = it->address().ipaddr().ToString();
+    int family = it->address().ipaddr().family();
+    if (family == AF_INET) {
+      addr_type->assign(kConnectionIpv4Addrtype);
+    } else if (family == AF_INET6) {
+      addr_type->assign(kConnectionIpv6Addrtype);
+    }
   }
-  return true;
 }
 
 // Update |mline|'s default destination and append a c line after it.
@@ -705,55 +717,52 @@
   }
 
   std::ostringstream os;
-  std::string rtp_port, rtp_ip;
-  if (GetDefaultDestination(candidates, ICE_CANDIDATE_COMPONENT_RTP,
-                            &rtp_port, &rtp_ip)) {
-    // Found default RTP candidate.
-    // RFC 5245
-    // The default candidates are added to the SDP as the default
-    // destination for media.  For streams based on RTP, this is done by
-    // placing the IP address and port of the RTP candidate into the c and m
-    // lines, respectively.
-
-    // Update the port in the m line.
-    // If this is a m-line with port equal to 0, we don't change it.
-    if (fields[1] != kMediaPortRejected) {
-      new_lines.replace(fields[0].size() + 1,
-                        fields[1].size(),
-                        rtp_port);
-    }
-    // Add the c line.
-    // RFC 4566
-    // c=<nettype> <addrtype> <connection-address>
-    InitLine(kLineTypeConnection, kConnectionNettype, &os);
-    os << " " << kConnectionAddrtype << " " << rtp_ip;
-    AddLine(os.str(), &new_lines);
+  std::string rtp_port, rtp_ip, addr_type;
+  GetDefaultDestination(candidates, ICE_CANDIDATE_COMPONENT_RTP,
+                        &rtp_port, &rtp_ip, &addr_type);
+  // Found default RTP candidate.
+  // RFC 5245
+  // The default candidates are added to the SDP as the default
+  // destination for media.  For streams based on RTP, this is done by
+  // placing the IP address and port of the RTP candidate into the c and m
+  // lines, respectively.
+  // Update the port in the m line.
+  // If this is a m-line with port equal to 0, we don't change it.
+  if (fields[1] != kMediaPortRejected) {
+    new_lines.replace(fields[0].size() + 1,
+                      fields[1].size(),
+                      rtp_port);
   }
+  // Add the c line.
+  // RFC 4566
+  // c=<nettype> <addrtype> <connection-address>
+  InitLine(kLineTypeConnection, kConnectionNettype, &os);
+  os << " " << addr_type << " " << rtp_ip;
+  AddLine(os.str(), &new_lines);
   message->append(new_lines);
 }
 
 // Gets "a=rtcp" line if found default RTCP candidate from |candidates|.
 static std::string GetRtcpLine(const std::vector<Candidate>& candidates) {
-  std::string rtcp_line, rtcp_port, rtcp_ip;
-  if (GetDefaultDestination(candidates, ICE_CANDIDATE_COMPONENT_RTCP,
-                            &rtcp_port, &rtcp_ip)) {
-    // Found default RTCP candidate.
-    // RFC 5245
-    // If the agent is utilizing RTCP, it MUST encode the RTCP candidate
-    // using the a=rtcp attribute as defined in RFC 3605.
+  std::string rtcp_line, rtcp_port, rtcp_ip, addr_type;
+  GetDefaultDestination(candidates, ICE_CANDIDATE_COMPONENT_RTCP,
+                        &rtcp_port, &rtcp_ip, &addr_type);
+  // Found default RTCP candidate.
+  // RFC 5245
+  // If the agent is utilizing RTCP, it MUST encode the RTCP candidate
+  // using the a=rtcp attribute as defined in RFC 3605.
 
-    // RFC 3605
-    // rtcp-attribute =  "a=rtcp:" port  [nettype space addrtype space
-    // connection-address] CRLF
-    std::ostringstream os;
-    InitAttrLine(kAttributeRtcp, &os);
-    os << kSdpDelimiterColon
-       << rtcp_port << " "
-       << kConnectionNettype << " "
-       << kConnectionAddrtype << " "
-       << rtcp_ip;
-    rtcp_line = os.str();
-  }
+  // RFC 3605
+  // rtcp-attribute =  "a=rtcp:" port  [nettype space addrtype space
+  // connection-address] CRLF
+  std::ostringstream os;
+  InitAttrLine(kAttributeRtcp, &os);
+  os << kSdpDelimiterColon
+     << rtcp_port << " "
+     << kConnectionNettype << " "
+     << addr_type << " "
+     << rtcp_ip;
+  rtcp_line = os.str();
   return rtcp_line;
 }
 
@@ -1243,7 +1252,7 @@
   // To reject an offered stream, the port number in the corresponding stream in
   // the answer MUST be set to zero.
   const std::string port = content_info->rejected ?
-      kMediaPortRejected : kDefaultPort;
+      kMediaPortRejected : kDummyPort;
 
   rtc::SSLFingerprint* fp = (transport_info) ?
       transport_info->description.identity_fingerprint.get() : NULL;
diff --git a/talk/app/webrtc/webrtcsdp_unittest.cc b/talk/app/webrtc/webrtcsdp_unittest.cc
index 560d5da..17701a1 100644
--- a/talk/app/webrtc/webrtcsdp_unittest.cc
+++ b/talk/app/webrtc/webrtcsdp_unittest.cc
@@ -212,9 +212,9 @@
     "s=-\r\n"
     "t=0 0\r\n"
     "a=msid-semantic: WMS local_stream_1 local_stream_2\r\n"
-    "m=audio 1 RTP/SAVPF 111 103 104\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
-    "a=rtcp:1 IN IP4 0.0.0.0\r\n"
+    "m=audio 9 RTP/SAVPF 111 103 104\r\n"
+    "c=IN IP6 ::\r\n"
+    "a=rtcp:9 IN IP6 ::\r\n"
     "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n"
     "a=mid:audio_content_name\r\n"
     "a=sendrecv\r\n"
@@ -233,9 +233,9 @@
     "a=ssrc:4 msid:local_stream_2 audio_track_id_2\r\n"
     "a=ssrc:4 mslabel:local_stream_2\r\n"
     "a=ssrc:4 label:audio_track_id_2\r\n"
-    "m=video 1 RTP/SAVPF 120\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
-    "a=rtcp:1 IN IP4 0.0.0.0\r\n"
+    "m=video 9 RTP/SAVPF 120\r\n"
+    "c=IN IP6 ::\r\n"
+    "a=rtcp:9 IN IP6 ::\r\n"
     "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n"
     "a=mid:video_content_name\r\n"
     "a=sendrecv\r\n"
@@ -261,9 +261,9 @@
     "a=ssrc:6 label:video_track_id_3\r\n";
 
 static const char kSdpRtpDataChannelString[] =
-    "m=application 1 RTP/SAVPF 101\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
-    "a=rtcp:1 IN IP4 0.0.0.0\r\n"
+    "m=application 9 RTP/SAVPF 101\r\n"
+    "c=IN IP6 ::\r\n"
+    "a=rtcp:9 IN IP6 ::\r\n"
     "a=ice-ufrag:ufrag_data\r\n"
     "a=ice-pwd:pwd_data\r\n"
     "a=mid:data_content_name\r\n"
@@ -277,8 +277,8 @@
     "a=ssrc:10 label:data_channeld0\r\n";
 
 static const char kSdpSctpDataChannelString[] =
-    "m=application 1 DTLS/SCTP 5000\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
+    "m=application 9 DTLS/SCTP 5000\r\n"
+    "c=IN IP6 ::\r\n"
     "a=ice-ufrag:ufrag_data\r\n"
     "a=ice-pwd:pwd_data\r\n"
     "a=mid:data_content_name\r\n"
@@ -286,10 +286,10 @@
 
 // draft-ietf-mmusic-sctp-sdp-07
 static const char kSdpSctpDataChannelStringWithSctpPort[] =
-    "m=application 1 DTLS/SCTP webrtc-datachannel\r\n"
+    "m=application 9 DTLS/SCTP webrtc-datachannel\r\n"
     "a=fmtp:webrtc-datachannel max-message-size=100000\r\n"
     "a=sctp-port 5000\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
+    "c=IN IP6 ::\r\n"
     "a=ice-ufrag:ufrag_data\r\n"
     "a=ice-pwd:pwd_data\r\n"
     "a=mid:data_content_name\r\n";
@@ -315,11 +315,11 @@
     "s=-\r\n"
     "t=0 0\r\n"
     "a=msid-semantic: WMS\r\n"
-    "m=audio 1 RTP/SAVPF 111 103 104\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
+    "m=audio 9 RTP/SAVPF 111 103 104\r\n"
+    "c=IN IP6 ::\r\n"
     "a=x-google-flag:conference\r\n"
-    "m=video 1 RTP/SAVPF 120\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
+    "m=video 9 RTP/SAVPF 120\r\n"
+    "c=IN IP6 ::\r\n"
     "a=x-google-flag:conference\r\n";
 
 static const char kSdpSessionString[] =
@@ -330,9 +330,9 @@
     "a=msid-semantic: WMS local_stream\r\n";
 
 static const char kSdpAudioString[] =
-    "m=audio 1 RTP/SAVPF 111\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
-    "a=rtcp:1 IN IP4 0.0.0.0\r\n"
+    "m=audio 9 RTP/SAVPF 111\r\n"
+    "c=IN IP6 ::\r\n"
+    "a=rtcp:9 IN IP6 ::\r\n"
     "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n"
     "a=mid:audio_content_name\r\n"
     "a=sendrecv\r\n"
@@ -343,9 +343,9 @@
     "a=ssrc:1 label:audio_track_id_1\r\n";
 
 static const char kSdpVideoString[] =
-    "m=video 1 RTP/SAVPF 120\r\n"
-    "c=IN IP4 0.0.0.0\r\n"
-    "a=rtcp:1 IN IP4 0.0.0.0\r\n"
+    "m=video 9 RTP/SAVPF 120\r\n"
+    "c=IN IP6 ::\r\n"
+    "a=rtcp:9 IN IP6 ::\r\n"
     "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n"
     "a=mid:video_content_name\r\n"
     "a=sendrecv\r\n"
@@ -1195,7 +1195,7 @@
         // description.
         "a=msid-semantic: WMS\r\n"
         // Pl type 111 preferred.
-        "m=audio 1 RTP/SAVPF 111 104 103 102\r\n"
+        "m=audio 9 RTP/SAVPF 111 104 103 102\r\n"
         // Pltype 111 listed before 103 and 104 in the map.
         "a=rtpmap:111 opus/48000/2\r\n"
         // Pltype 103 listed before 104.
@@ -1217,7 +1217,7 @@
     os.clear();
     os.str("");
     // Pl type 100 preferred.
-    os << "m=video 1 RTP/SAVPF 99 95\r\n"
+    os << "m=video 9 RTP/SAVPF 99 95\r\n"
        << "a=rtpmap:99 VP8/90000\r\n"
        << "a=rtpmap:95 RTX/90000\r\n"
        << "a=fmtp:95 apt=99;rtx-time=1000\r\n";
@@ -1279,7 +1279,7 @@
         // this parser, and will be added to the SDP when serializing a session
         // description.
         "a=msid-semantic: WMS\r\n"
-        "m=audio 1 RTP/SAVPF 111\r\n"
+        "m=audio 9 RTP/SAVPF 111\r\n"
         "a=rtpmap:111 opus/48000/2\r\n"
         "a=rtcp-fb:111 nack\r\n"
         "m=video 3457 RTP/SAVPF 101\r\n"
@@ -1596,7 +1596,7 @@
   // TODO(pthatcher): We need to temporarily allow the SDP to control
   // this for backwards-compatibility.  Once we don't need that any
   // more, remove this.
-  InjectAfter("m=application 1 RTP/SAVPF 101\r\nc=IN IP4 0.0.0.0\r\n",
+  InjectAfter("m=application 9 RTP/SAVPF 101\r\nc=IN IP6 ::\r\n",
               "b=AS:100\r\n",
               &expected_sdp);
   EXPECT_EQ(expected_sdp, message);
@@ -2308,7 +2308,7 @@
       "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
       "s=-\r\n"
       "t=0 0\r\n"
-      "m=audio 1 RTP/SAVPF 104 103\r\n"  // Pl type 104 preferred.
+      "m=audio 9 RTP/SAVPF 104 103\r\n"  // Pl type 104 preferred.
       "a=rtpmap:111 opus/48000/2\r\n"  // Pltype 111 listed before 103 and 104
                                        // in the map.
       "a=rtpmap:103 ISAC/16000\r\n"  // Pltype 103 listed before 104 in the map.