configuration.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /**
  2. * Copyright (c) 2019 Paul-Louis Ageneau
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "configuration.hpp"
  19. #include <regex>
  20. namespace rtc {
  21. IceServer::IceServer(const string &url) {
  22. // Modified regex from RFC 3986, see https://tools.ietf.org/html/rfc3986#appendix-B
  23. static const char *rs =
  24. R"(^(([^:.@/?#]+):)?(/{0,2}((([^:@]*)(:([^@]*))?)@)?(([^:/?#]*)(:([^/?#]*))?))?([^?#]*)(\?([^#]*))?(#(.*))?)";
  25. static const std::regex r(rs, std::regex::extended);
  26. std::smatch m;
  27. if (!std::regex_match(url, m, r) || m[10].length() == 0)
  28. throw std::invalid_argument("Invalid ICE server URL: " + url);
  29. std::vector<optional<string>> opt(m.size());
  30. std::transform(m.begin(), m.end(), opt.begin(), [](const auto &sm) {
  31. return sm.length() > 0 ? std::make_optional(string(sm)) : nullopt;
  32. });
  33. string scheme = opt[2].value_or("stun");
  34. relayType = RelayType::TurnUdp;
  35. if (scheme == "stun" || scheme == "STUN")
  36. type = Type::Stun;
  37. else if (scheme == "turn" || scheme == "TURN")
  38. type = Type::Turn;
  39. else if (scheme == "turns" || scheme == "TURNS") {
  40. type = Type::Turn;
  41. relayType = RelayType::TurnTls;
  42. } else
  43. throw std::invalid_argument("Unknown ICE server protocol: " + scheme);
  44. if (auto &query = opt[15]) {
  45. if (query->find("transport=udp") != string::npos)
  46. relayType = RelayType::TurnUdp;
  47. if (query->find("transport=tcp") != string::npos)
  48. relayType = RelayType::TurnTcp;
  49. if (query->find("transport=tls") != string::npos)
  50. relayType = RelayType::TurnTls;
  51. }
  52. username = opt[6].value_or("");
  53. password = opt[8].value_or("");
  54. hostname = opt[10].value();
  55. while (!hostname.empty() && hostname.front() == '[')
  56. hostname.erase(hostname.begin());
  57. while (!hostname.empty() && hostname.back() == ']')
  58. hostname.pop_back();
  59. string service = opt[12].value_or(relayType == RelayType::TurnTls ? "5349" : "3478");
  60. try {
  61. port = uint16_t(std::stoul(service));
  62. } catch (...) {
  63. throw std::invalid_argument("Invalid ICE server port in URL: " + service);
  64. }
  65. }
  66. IceServer::IceServer(string hostname_, uint16_t port_)
  67. : hostname(std::move(hostname_)), port(port_), type(Type::Stun) {}
  68. IceServer::IceServer(string hostname_, string service_)
  69. : hostname(std::move(hostname_)), type(Type::Stun) {
  70. try {
  71. port = uint16_t(std::stoul(service_));
  72. } catch (...) {
  73. throw std::invalid_argument("Invalid ICE server port: " + service_);
  74. }
  75. }
  76. IceServer::IceServer(string hostname_, uint16_t port_, string username_, string password_,
  77. RelayType relayType_)
  78. : hostname(std::move(hostname_)), port(port_), type(Type::Turn), username(std::move(username_)),
  79. password(std::move(password_)), relayType(relayType_) {}
  80. IceServer::IceServer(string hostname_, string service_, string username_, string password_,
  81. RelayType relayType_)
  82. : hostname(std::move(hostname_)), type(Type::Turn), username(std::move(username_)),
  83. password(std::move(password_)), relayType(relayType_) {
  84. try {
  85. port = uint16_t(std::stoul(service_));
  86. } catch (...) {
  87. throw std::invalid_argument("Invalid ICE server port: " + service_);
  88. }
  89. }
  90. ProxyServer::ProxyServer(Type type_, string hostname_, uint16_t port_, string username_,
  91. string password_)
  92. : type(type_), hostname(hostname_), port(port_), username(username_), password(password_) {}
  93. } // namespace rtc