Shaka Packager SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
udp_options.cc
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/file/udp_options.h"
8 
9 #include <gflags/gflags.h>
10 
11 #include "packager/base/strings/string_number_conversions.h"
12 #include "packager/base/strings/string_split.h"
13 
14 DEFINE_string(udp_interface_address,
15  "",
16  "IP address of the interface over which to receive UDP unicast"
17  " or multicast streams");
18 
19 namespace shaka {
20 
21 namespace {
22 
23 enum FieldType {
24  kUnknownField = 0,
25  kReuseField,
26  kInterfaceAddressField,
27  kTimeoutField,
28 };
29 
30 struct FieldNameToTypeMapping {
31  const char* field_name;
32  FieldType field_type;
33 };
34 
35 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
36  {"reuse", kReuseField},
37  {"interface", kInterfaceAddressField},
38  {"source", kInterfaceAddressField},
39  {"timeout", kTimeoutField},
40 };
41 
42 FieldType GetFieldType(const std::string& field_name) {
43  for (size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
44  if (field_name == kFieldNameTypeMappings[idx].field_name)
45  return kFieldNameTypeMappings[idx].field_type;
46  }
47  return kUnknownField;
48 }
49 
50 bool StringToAddressAndPort(base::StringPiece addr_and_port,
51  std::string* addr,
52  uint16_t* port) {
53  DCHECK(addr);
54  DCHECK(port);
55 
56  const size_t colon_pos = addr_and_port.find(':');
57  if (colon_pos == base::StringPiece::npos) {
58  return false;
59  }
60  *addr = addr_and_port.substr(0, colon_pos).as_string();
61  unsigned port_value;
62  if (!base::StringToUint(addr_and_port.substr(colon_pos + 1), &port_value) ||
63  (port_value > 65535)) {
64  return false;
65  }
66  *port = port_value;
67  return true;
68 }
69 
70 } // namespace
71 
72 std::unique_ptr<UdpOptions> UdpOptions::ParseFromString(
73  base::StringPiece udp_url) {
74  std::unique_ptr<UdpOptions> options(new UdpOptions);
75 
76  const size_t question_mark_pos = udp_url.find('?');
77  base::StringPiece address_str = udp_url.substr(0, question_mark_pos);
78 
79  if (question_mark_pos != base::StringPiece::npos) {
80  base::StringPiece options_str = udp_url.substr(question_mark_pos + 1);
81 
82  base::StringPairs pairs;
83  if (!base::SplitStringIntoKeyValuePairs(options_str, '=', '&', &pairs)) {
84  LOG(ERROR) << "Invalid udp options name/value pairs " << options_str;
85  return nullptr;
86  }
87  for (const auto& pair : pairs) {
88  switch (GetFieldType(pair.first)) {
89  case kReuseField: {
90  int reuse_value = 0;
91  if (!base::StringToInt(pair.second, &reuse_value)) {
92  LOG(ERROR) << "Invalid udp option for reuse field " << pair.second;
93  return nullptr;
94  }
95  options->reuse_ = reuse_value > 0;
96  break;
97  }
98  case kInterfaceAddressField:
99  options->interface_address_ = pair.second;
100  break;
101  case kTimeoutField:
102  if (!base::StringToUint(pair.second, &options->timeout_us_)) {
103  LOG(ERROR) << "Invalid udp option for timeout field "
104  << pair.second;
105  return nullptr;
106  }
107  break;
108  default:
109  LOG(ERROR) << "Unknown field in udp options (\"" << pair.first
110  << "\").";
111  return nullptr;
112  }
113  }
114  }
115 
116  if (!FLAGS_udp_interface_address.empty()) {
117  LOG(WARNING) << "--udp_interface_address is deprecated. Consider switching "
118  "to udp options instead, something like "
119  "udp:://ip:port?interface=interface_ip.";
120  options->interface_address_ = FLAGS_udp_interface_address;
121  }
122 
123  if (!StringToAddressAndPort(address_str, &options->address_,
124  &options->port_)) {
125  LOG(ERROR) << "Malformed address:port UDP url " << address_str;
126  return nullptr;
127  }
128  return options;
129 }
130 
131 } // namespace shaka
static std::unique_ptr< UdpOptions > ParseFromString(base::StringPiece udp_url)
Definition: udp_options.cc:72
Options parsed from UDP url string of the form: udp://ip:port[?options].
Definition: udp_options.h:15