configuration.cpp 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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<std::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. service = opt[12].value_or(relayType == RelayType::TurnTls ? "5349" : "3478");
  56. while (!hostname.empty() && hostname.front() == '[')
  57. hostname.erase(hostname.begin());
  58. while (!hostname.empty() && hostname.back() == ']')
  59. hostname.pop_back();
  60. }
  61. IceServer::IceServer(string hostname_, uint16_t port_)
  62. : IceServer(std::move(hostname_), std::to_string(port_)) {}
  63. IceServer::IceServer(string hostname_, string service_)
  64. : hostname(std::move(hostname_)), service(std::move(service_)), type(Type::Stun) {}
  65. IceServer::IceServer(string hostname_, uint16_t port_, string username_, string password_,
  66. RelayType relayType_)
  67. : IceServer(hostname_, std::to_string(port_), std::move(username_), std::move(password_),
  68. relayType_) {}
  69. IceServer::IceServer(string hostname_, string service_, string username_, string password_,
  70. RelayType relayType_)
  71. : hostname(std::move(hostname_)), service(std::move(service_)), type(Type::Turn),
  72. username(std::move(username_)), password(std::move(password_)), relayType(relayType_) {}
  73. ProxyServer::ProxyServer(Type type_, string ip_, uint16_t port_, string username_, string password_)
  74. : type(type_), ip(ip_), port(port_), username(username_), password(password_) {}
  75. } // namespace rtc