test_turn_server.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright 2012 The WebRTC Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef P2P_BASE_TEST_TURN_SERVER_H_
  11. #define P2P_BASE_TEST_TURN_SERVER_H_
  12. #include <string>
  13. #include <vector>
  14. #include "api/transport/stun.h"
  15. #include "p2p/base/basic_packet_socket_factory.h"
  16. #include "p2p/base/turn_server.h"
  17. #include "rtc_base/async_udp_socket.h"
  18. #include "rtc_base/ssl_adapter.h"
  19. #include "rtc_base/ssl_identity.h"
  20. #include "rtc_base/thread.h"
  21. #include "rtc_base/thread_checker.h"
  22. namespace cricket {
  23. static const char kTestRealm[] = "example.org";
  24. static const char kTestSoftware[] = "TestTurnServer";
  25. class TestTurnRedirector : public TurnRedirectInterface {
  26. public:
  27. explicit TestTurnRedirector(const std::vector<rtc::SocketAddress>& addresses)
  28. : alternate_server_addresses_(addresses),
  29. iter_(alternate_server_addresses_.begin()) {}
  30. virtual bool ShouldRedirect(const rtc::SocketAddress&,
  31. rtc::SocketAddress* out) {
  32. if (!out || iter_ == alternate_server_addresses_.end()) {
  33. return false;
  34. }
  35. *out = *iter_++;
  36. return true;
  37. }
  38. private:
  39. const std::vector<rtc::SocketAddress>& alternate_server_addresses_;
  40. std::vector<rtc::SocketAddress>::const_iterator iter_;
  41. };
  42. class TestTurnServer : public TurnAuthInterface {
  43. public:
  44. TestTurnServer(rtc::Thread* thread,
  45. const rtc::SocketAddress& int_addr,
  46. const rtc::SocketAddress& udp_ext_addr,
  47. ProtocolType int_protocol = PROTO_UDP,
  48. bool ignore_bad_cert = true,
  49. const std::string& common_name = "test turn server")
  50. : server_(thread), thread_(thread) {
  51. AddInternalSocket(int_addr, int_protocol, ignore_bad_cert, common_name);
  52. server_.SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(thread),
  53. udp_ext_addr);
  54. server_.set_realm(kTestRealm);
  55. server_.set_software(kTestSoftware);
  56. server_.set_auth_hook(this);
  57. }
  58. ~TestTurnServer() { RTC_DCHECK(thread_checker_.IsCurrent()); }
  59. void set_enable_otu_nonce(bool enable) {
  60. RTC_DCHECK(thread_checker_.IsCurrent());
  61. server_.set_enable_otu_nonce(enable);
  62. }
  63. TurnServer* server() {
  64. RTC_DCHECK(thread_checker_.IsCurrent());
  65. return &server_;
  66. }
  67. void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
  68. RTC_DCHECK(thread_checker_.IsCurrent());
  69. server_.set_redirect_hook(redirect_hook);
  70. }
  71. void set_enable_permission_checks(bool enable) {
  72. RTC_DCHECK(thread_checker_.IsCurrent());
  73. server_.set_enable_permission_checks(enable);
  74. }
  75. void AddInternalSocket(const rtc::SocketAddress& int_addr,
  76. ProtocolType proto,
  77. bool ignore_bad_cert = true,
  78. const std::string& common_name = "test turn server") {
  79. RTC_DCHECK(thread_checker_.IsCurrent());
  80. if (proto == cricket::PROTO_UDP) {
  81. server_.AddInternalSocket(
  82. rtc::AsyncUDPSocket::Create(thread_->socketserver(), int_addr),
  83. proto);
  84. } else if (proto == cricket::PROTO_TCP || proto == cricket::PROTO_TLS) {
  85. // For TCP we need to create a server socket which can listen for incoming
  86. // new connections.
  87. rtc::AsyncSocket* socket =
  88. thread_->socketserver()->CreateAsyncSocket(AF_INET, SOCK_STREAM);
  89. if (proto == cricket::PROTO_TLS) {
  90. // For TLS, wrap the TCP socket with an SSL adapter. The adapter must
  91. // be configured with a self-signed certificate for testing.
  92. // Additionally, the client will not present a valid certificate, so we
  93. // must not fail when checking the peer's identity.
  94. rtc::SSLAdapter* adapter = rtc::SSLAdapter::Create(socket);
  95. adapter->SetRole(rtc::SSL_SERVER);
  96. adapter->SetIdentity(
  97. rtc::SSLIdentity::Create(common_name, rtc::KeyParams()));
  98. adapter->SetIgnoreBadCert(ignore_bad_cert);
  99. socket = adapter;
  100. }
  101. socket->Bind(int_addr);
  102. socket->Listen(5);
  103. server_.AddInternalServerSocket(socket, proto);
  104. } else {
  105. RTC_NOTREACHED() << "Unknown protocol type: " << proto;
  106. }
  107. }
  108. // Finds the first allocation in the server allocation map with a source
  109. // ip and port matching the socket address provided.
  110. TurnServerAllocation* FindAllocation(const rtc::SocketAddress& src) {
  111. RTC_DCHECK(thread_checker_.IsCurrent());
  112. const TurnServer::AllocationMap& map = server_.allocations();
  113. for (TurnServer::AllocationMap::const_iterator it = map.begin();
  114. it != map.end(); ++it) {
  115. if (src == it->first.src()) {
  116. return it->second.get();
  117. }
  118. }
  119. return NULL;
  120. }
  121. private:
  122. // For this test server, succeed if the password is the same as the username.
  123. // Obviously, do not use this in a production environment.
  124. virtual bool GetKey(const std::string& username,
  125. const std::string& realm,
  126. std::string* key) {
  127. RTC_DCHECK(thread_checker_.IsCurrent());
  128. return ComputeStunCredentialHash(username, realm, username, key);
  129. }
  130. TurnServer server_;
  131. rtc::Thread* thread_;
  132. rtc::ThreadChecker thread_checker_;
  133. };
  134. } // namespace cricket
  135. #endif // P2P_BASE_TEST_TURN_SERVER_H_