1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "host/frontend/webrtc/lib/port_range_socket_factory.h"
18
19 #include <android-base/logging.h>
20
21 namespace cuttlefish {
22 namespace webrtc_streaming {
23
24 namespace {
25
IntersectPortRanges(std::pair<uint16_t,uint16_t> own_range,uint16_t min_port,uint16_t max_port)26 std::pair<uint16_t, uint16_t> IntersectPortRanges(
27 std::pair<uint16_t, uint16_t> own_range, uint16_t min_port,
28 uint16_t max_port) {
29 if (own_range.first == own_range.second && own_range.first == 0) {
30 // No range configured
31 return {min_port, max_port};
32 }
33 if (min_port == max_port && max_port == 0) {
34 // No range requested, use configured
35 return own_range;
36 }
37 uint16_t own_min_port = own_range.first;
38 uint16_t own_max_port = own_range.second;
39
40 if (min_port > own_max_port || max_port < own_min_port) {
41 // Ranges don't intersect
42 LOG(WARNING) << "Port ranges don't intersect: requested=[" << min_port
43 << "," << max_port << "], configured=[" << own_min_port << ","
44 << own_max_port << "]";
45 }
46 return {std::max(min_port, own_min_port), std::min(max_port, own_max_port)};
47 }
48
49 } // namespace
50
PortRangeSocketFactory(rtc::Thread * thread,std::pair<uint16_t,uint16_t> udp_port_range,std::pair<uint16_t,uint16_t> tcp_port_range)51 PortRangeSocketFactory::PortRangeSocketFactory(
52 rtc::Thread* thread, std::pair<uint16_t, uint16_t> udp_port_range,
53 std::pair<uint16_t, uint16_t> tcp_port_range)
54 : rtc::BasicPacketSocketFactory(thread),
55 udp_port_range_(udp_port_range),
56 tcp_port_range_(tcp_port_range) {}
57
CreateUdpSocket(const rtc::SocketAddress & local_address,uint16_t min_port,uint16_t max_port)58 rtc::AsyncPacketSocket* PortRangeSocketFactory::CreateUdpSocket(
59 const rtc::SocketAddress& local_address, uint16_t min_port,
60 uint16_t max_port) {
61 auto port_range = IntersectPortRanges(udp_port_range_, min_port, max_port);
62 if (port_range.second < port_range.first) {
63 // Own range doesn't intersect with requested range
64 return nullptr;
65 }
66 return rtc::BasicPacketSocketFactory::CreateUdpSocket(
67 local_address, port_range.first, port_range.second);
68 }
69
CreateServerTcpSocket(const rtc::SocketAddress & local_address,uint16_t min_port,uint16_t max_port,int opts)70 rtc::AsyncPacketSocket* PortRangeSocketFactory::CreateServerTcpSocket(
71 const rtc::SocketAddress& local_address, uint16_t min_port,
72 uint16_t max_port, int opts) {
73 auto port_range = IntersectPortRanges(tcp_port_range_, min_port, max_port);
74 if (port_range.second < port_range.first) {
75 // Own range doesn't intersect with requested range
76 return nullptr;
77 }
78
79 return rtc::BasicPacketSocketFactory::CreateServerTcpSocket(
80 local_address, port_range.first, port_range.second, opts);
81 }
82
83 } // namespace webrtc_streaming
84 } // namespace cuttlefish
85