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