Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / port_unittest.cc
index 3ea6375..a6365d5 100644 (file)
@@ -34,6 +34,7 @@
 #include "talk/base/physicalsocketserver.h"
 #include "talk/base/scoped_ptr.h"
 #include "talk/base/socketaddress.h"
+#include "talk/base/ssladapter.h"
 #include "talk/base/stringutils.h"
 #include "talk/base/thread.h"
 #include "talk/base/virtualsocketserver.h"
@@ -172,7 +173,7 @@ class TestPort : public Port {
   }
   virtual int SendTo(
       const void* data, size_t size, const talk_base::SocketAddress& addr,
-      talk_base::DiffServCodePoint dscp, bool payload) {
+      const talk_base::PacketOptions& options, bool payload) {
     if (!payload) {
       IceMessage* msg = new IceMessage;
       ByteBuffer* buf = new ByteBuffer(static_cast<const char*>(data), size);
@@ -355,10 +356,14 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
 
  protected:
   static void SetUpTestCase() {
-    // Ensure the RNG is inited.
-    talk_base::InitRandom(NULL, 0);
+    talk_base::InitializeSSL();
   }
 
+  static void TearDownTestCase() {
+    talk_base::CleanupSSL();
+  }
+
+
   void TestLocalToLocal() {
     Port* port1 = CreateUdpPort(kLocalAddr1);
     Port* port2 = CreateUdpPort(kLocalAddr2);
@@ -837,11 +842,11 @@ class FakeAsyncPacketSocket : public AsyncPacketSocket {
 
   // Send a packet.
   virtual int Send(const void *pv, size_t cb,
-                   talk_base::DiffServCodePoint dscp) {
+                   const talk_base::PacketOptions& options) {
     return static_cast<int>(cb);
   }
   virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
-                     talk_base::DiffServCodePoint dscp) {
+                     const talk_base::PacketOptions& options) {
     return static_cast<int>(cb);
   }
   virtual int Close() {
@@ -1280,21 +1285,37 @@ TEST_F(PortTest, TestSkipCrossFamilyUdp) {
 // This test verifies DSCP value set through SetOption interface can be
 // get through DefaultDscpValue.
 TEST_F(PortTest, TestDefaultDscpValue) {
+  int dscp;
   talk_base::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
-  udpport->SetOption(talk_base::Socket::OPT_DSCP, talk_base::DSCP_CS6);
-  EXPECT_EQ(talk_base::DSCP_CS6, udpport->DefaultDscpValue());
+  EXPECT_EQ(0, udpport->SetOption(talk_base::Socket::OPT_DSCP,
+                                  talk_base::DSCP_CS6));
+  EXPECT_EQ(0, udpport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
   talk_base::scoped_ptr<TCPPort> tcpport(CreateTcpPort(kLocalAddr1));
-  tcpport->SetOption(talk_base::Socket::OPT_DSCP, talk_base::DSCP_AF31);
-  EXPECT_EQ(talk_base::DSCP_AF31, tcpport->DefaultDscpValue());
+  EXPECT_EQ(0, tcpport->SetOption(talk_base::Socket::OPT_DSCP,
+                                 talk_base::DSCP_AF31));
+  EXPECT_EQ(0, tcpport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
+  EXPECT_EQ(talk_base::DSCP_AF31, dscp);
   talk_base::scoped_ptr<StunPort> stunport(
       CreateStunPort(kLocalAddr1, nat_socket_factory1()));
-  stunport->SetOption(talk_base::Socket::OPT_DSCP, talk_base::DSCP_AF41);
-  EXPECT_EQ(talk_base::DSCP_AF41, stunport->DefaultDscpValue());
-  talk_base::scoped_ptr<TurnPort> turnport(CreateTurnPort(
+  EXPECT_EQ(0, stunport->SetOption(talk_base::Socket::OPT_DSCP,
+                                  talk_base::DSCP_AF41));
+  EXPECT_EQ(0, stunport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
+  EXPECT_EQ(talk_base::DSCP_AF41, dscp);
+  talk_base::scoped_ptr<TurnPort> turnport1(CreateTurnPort(
+      kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
+  // Socket is created in PrepareAddress.
+  turnport1->PrepareAddress();
+  EXPECT_EQ(0, turnport1->SetOption(talk_base::Socket::OPT_DSCP,
+                                  talk_base::DSCP_CS7));
+  EXPECT_EQ(0, turnport1->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
+  EXPECT_EQ(talk_base::DSCP_CS7, dscp);
+  // This will verify correct value returned without the socket.
+  talk_base::scoped_ptr<TurnPort> turnport2(CreateTurnPort(
       kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
-  turnport->SetOption(talk_base::Socket::OPT_DSCP, talk_base::DSCP_CS7);
-  EXPECT_EQ(talk_base::DSCP_CS7, turnport->DefaultDscpValue());
-  // TODO(mallinath) - Test DSCP through GetOption.
+  EXPECT_EQ(0, turnport2->SetOption(talk_base::Socket::OPT_DSCP,
+                                  talk_base::DSCP_CS6));
+  EXPECT_EQ(0, turnport2->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
+  EXPECT_EQ(talk_base::DSCP_CS6, dscp);
 }
 
 // Test sending STUN messages in GICE format.
@@ -1665,6 +1686,81 @@ TEST_F(PortTest, TestHandleStunMessageAsIce) {
       out_msg->GetErrorCode()->reason());
 }
 
+// This test verifies port can handle ICE messages in Hybrid mode and switches
+// ICEPROTO_RFC5245 mode after successfully handling the message.
+TEST_F(PortTest, TestHandleStunMessageAsIceInHybridMode) {
+  // Our port will act as the "remote" port.
+  talk_base::scoped_ptr<TestPort> port(
+      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+  port->SetIceProtocolType(ICEPROTO_HYBRID);
+
+  talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
+  talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+  talk_base::SocketAddress addr(kLocalAddr1);
+  std::string username;
+
+  // BINDING-REQUEST from local to remote with valid ICE username,
+  // MESSAGE-INTEGRITY, and FINGERPRINT.
+  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+                                             "rfrag:lfrag"));
+  in_msg->AddMessageIntegrity("rpass");
+  in_msg->AddFingerprint();
+  WriteStunMessage(in_msg.get(), buf.get());
+  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+                                   out_msg.accept(), &username));
+  EXPECT_TRUE(out_msg.get() != NULL);
+  EXPECT_EQ("lfrag", username);
+  EXPECT_EQ(ICEPROTO_RFC5245, port->IceProtocol());
+}
+
+// This test verifies port can handle GICE messages in Hybrid mode and switches
+// ICEPROTO_GOOGLE mode after successfully handling the message.
+TEST_F(PortTest, TestHandleStunMessageAsGiceInHybridMode) {
+  // Our port will act as the "remote" port.
+  talk_base::scoped_ptr<TestPort> port(
+      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+  port->SetIceProtocolType(ICEPROTO_HYBRID);
+
+  talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
+  talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+  talk_base::SocketAddress addr(kLocalAddr1);
+  std::string username;
+
+  // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
+  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+                                             "rfraglfrag"));
+  WriteStunMessage(in_msg.get(), buf.get());
+  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+                                   out_msg.accept(), &username));
+  EXPECT_TRUE(out_msg.get() != NULL);  // Succeeds, since this is GICE.
+  EXPECT_EQ("lfrag", username);
+  EXPECT_EQ(ICEPROTO_GOOGLE, port->IceProtocol());
+}
+
+// Verify port is not switched out of RFC5245 mode if GICE message is received
+// in that mode.
+TEST_F(PortTest, TestHandleStunMessageAsGiceInIceMode) {
+  // Our port will act as the "remote" port.
+  talk_base::scoped_ptr<TestPort> port(
+      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+  port->SetIceProtocolType(ICEPROTO_RFC5245);
+
+  talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
+  talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+  talk_base::SocketAddress addr(kLocalAddr1);
+  std::string username;
+
+  // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
+  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+                                             "rfraglfrag"));
+  WriteStunMessage(in_msg.get(), buf.get());
+  // Should fail as there is no MI and fingerprint.
+  EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+                                    out_msg.accept(), &username));
+  EXPECT_EQ(ICEPROTO_RFC5245, port->IceProtocol());
+}
+
+
 // Tests handling of GICE binding requests with missing or incorrect usernames.
 TEST_F(PortTest, TestHandleStunMessageAsGiceBadUsername) {
   talk_base::scoped_ptr<TestPort> port(
@@ -2201,16 +2297,15 @@ TEST_F(PortTest, TestWritableState) {
   // Data should be unsendable until the connection is accepted.
   char data[] = "abcd";
   int data_size = ARRAY_SIZE(data);
-  EXPECT_EQ(SOCKET_ERROR,
-            ch1.conn()->Send(data, data_size, talk_base::DSCP_NO_CHANGE));
+  talk_base::PacketOptions options;
+  EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
 
   // Accept the connection to return the binding response, transition to
   // writable, and allow data to be sent.
   ch2.AcceptConnection();
   EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
                  kTimeout);
-  EXPECT_EQ(data_size,
-            ch1.conn()->Send(data, data_size, talk_base::DSCP_NO_CHANGE));
+  EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
 
   // Ask the connection to update state as if enough time has passed to lose
   // full writability and 5 pings went unresponded to. We'll accomplish the
@@ -2223,8 +2318,7 @@ TEST_F(PortTest, TestWritableState) {
   EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
 
   // Data should be able to be sent in this state.
-  EXPECT_EQ(data_size,
-            ch1.conn()->Send(data, data_size, talk_base::DSCP_NO_CHANGE));
+  EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
 
   // And now allow the other side to process the pings and send binding
   // responses.
@@ -2241,8 +2335,7 @@ TEST_F(PortTest, TestWritableState) {
   EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
 
   // Now that the connection has completely timed out, data send should fail.
-  EXPECT_EQ(SOCKET_ERROR,
-            ch1.conn()->Send(data, data_size, talk_base::DSCP_NO_CHANGE));
+  EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
 
   ch1.Stop();
   ch2.Stop();