turnserver_main.cc (3366B)
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 11 #include <fstream> 12 #include <iostream> 13 #include <map> 14 #include <memory> 15 #include <string> 16 #include <utility> 17 18 #include "absl/strings/string_view.h" 19 #include "api/environment/environment.h" 20 #include "api/environment/environment_factory.h" 21 #include "examples/turnserver/read_auth_file.h" 22 #include "p2p/base/basic_packet_socket_factory.h" 23 #include "p2p/base/port_interface.h" 24 #include "p2p/test/turn_server.h" 25 #include "rtc_base/async_udp_socket.h" 26 #include "rtc_base/ip_address.h" 27 #include "rtc_base/physical_socket_server.h" 28 #include "rtc_base/socket_address.h" 29 #include "rtc_base/thread.h" 30 31 namespace { 32 const char kSoftware[] = "libjingle TurnServer"; 33 34 class TurnFileAuth : public webrtc::TurnAuthInterface { 35 public: 36 explicit TurnFileAuth(std::map<std::string, std::string> name_to_key) 37 : name_to_key_(std::move(name_to_key)) {} 38 39 bool GetKey(absl::string_view username, 40 absl::string_view realm, 41 std::string* key) override { 42 // File is stored as lines of <username>=<HA1>. 43 // Generate HA1 via "echo -n "<username>:<realm>:<password>" | md5sum" 44 auto it = name_to_key_.find(std::string(username)); 45 if (it == name_to_key_.end()) 46 return false; 47 *key = it->second; 48 return true; 49 } 50 51 private: 52 const std::map<std::string, std::string> name_to_key_; 53 }; 54 55 } // namespace 56 57 int main(int argc, char* argv[]) { 58 if (argc != 5) { 59 std::cerr << "usage: turnserver int-addr ext-ip realm auth-file" 60 << std::endl; 61 return 1; 62 } 63 64 webrtc::SocketAddress int_addr; 65 if (!int_addr.FromString(argv[1])) { 66 std::cerr << "Unable to parse IP address: " << argv[1] << std::endl; 67 return 1; 68 } 69 70 webrtc::IPAddress ext_addr; 71 if (!webrtc::IPFromString(argv[2], &ext_addr)) { 72 std::cerr << "Unable to parse IP address: " << argv[2] << std::endl; 73 return 1; 74 } 75 76 const webrtc::Environment env = webrtc::CreateEnvironment(); 77 webrtc::PhysicalSocketServer socket_server; 78 webrtc::AutoSocketServerThread main(&socket_server); 79 std::unique_ptr<webrtc::AsyncUDPSocket> int_socket = 80 webrtc::AsyncUDPSocket::Create(env, int_addr, socket_server); 81 if (!int_socket) { 82 std::cerr << "Failed to create a UDP socket bound at" << int_addr.ToString() 83 << std::endl; 84 return 1; 85 } 86 87 webrtc::TurnServer server(env, &main); 88 std::fstream auth_file(argv[4], std::fstream::in); 89 90 TurnFileAuth auth(auth_file.is_open() 91 ? webrtc_examples::ReadAuthFile(&auth_file) 92 : std::map<std::string, std::string>()); 93 server.set_realm(argv[3]); 94 server.set_software(kSoftware); 95 server.set_auth_hook(&auth); 96 server.AddInternalSocket(std::move(int_socket), webrtc::PROTO_UDP); 97 server.SetExternalSocketFactory( 98 new webrtc::BasicPacketSocketFactory(&socket_server), 99 webrtc::SocketAddress(ext_addr, 0)); 100 101 std::cout << "Listening internally at " << int_addr.ToString() << std::endl; 102 103 main.Run(); 104 return 0; 105 }