Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: webrtc/base/natserver.cc

Issue 1215713003: Ensuring that UDP TURN servers are always used as STUN servers. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing compiler warning from size_t->int cast Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/natserver.h ('k') | webrtc/base/natsocketfactory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/base/natsocketfactory.h" 11 #include "webrtc/base/natsocketfactory.h"
12 #include "webrtc/base/natserver.h" 12 #include "webrtc/base/natserver.h"
13 #include "webrtc/base/logging.h" 13 #include "webrtc/base/logging.h"
14 #include "webrtc/base/socketadapters.h"
14 15
15 namespace rtc { 16 namespace rtc {
16 17
17 RouteCmp::RouteCmp(NAT* nat) : symmetric(nat->IsSymmetric()) { 18 RouteCmp::RouteCmp(NAT* nat) : symmetric(nat->IsSymmetric()) {
18 } 19 }
19 20
20 size_t RouteCmp::operator()(const SocketAddressPair& r) const { 21 size_t RouteCmp::operator()(const SocketAddressPair& r) const {
21 size_t h = r.source().Hash(); 22 size_t h = r.source().Hash();
22 if (symmetric) 23 if (symmetric)
23 h ^= r.destination().Hash(); 24 h ^= r.destination().Hash();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 return true; 57 return true;
57 if (use_ip && (a2.ipaddr() < a1.ipaddr())) 58 if (use_ip && (a2.ipaddr() < a1.ipaddr()))
58 return false; 59 return false;
59 if (use_port && (a1.port() < a2.port())) 60 if (use_port && (a1.port() < a2.port()))
60 return true; 61 return true;
61 if (use_port && (a2.port() < a1.port())) 62 if (use_port && (a2.port() < a1.port()))
62 return false; 63 return false;
63 return false; 64 return false;
64 } 65 }
65 66
67 // Proxy socket that will capture the external destination address intended for
68 // a TCP connection to the NAT server.
69 class NATProxyServerSocket : public AsyncProxyServerSocket {
70 public:
71 NATProxyServerSocket(AsyncSocket* socket)
72 : AsyncProxyServerSocket(socket, kNATEncodedIPv6AddressSize) {
73 BufferInput(true);
74 }
75
76 void SendConnectResult(int err, const SocketAddress& addr) override {
77 char code = err ? 1 : 0;
78 BufferedReadAdapter::DirectSend(&code, sizeof(char));
79 }
80
81 protected:
82 void ProcessInput(char* data, size_t* len) override {
83 if (*len < 2) {
84 return;
85 }
86
87 int family = data[1];
88 ASSERT(family == AF_INET || family == AF_INET6);
89 if ((family == AF_INET && *len < kNATEncodedIPv4AddressSize) ||
90 (family == AF_INET6 && *len < kNATEncodedIPv6AddressSize)) {
91 return;
92 }
93
94 SocketAddress dest_addr;
95 size_t address_length = UnpackAddressFromNAT(data, *len, &dest_addr);
96
97 *len -= address_length;
98 if (*len > 0) {
99 memmove(data, data + address_length, *len);
100 }
101
102 bool remainder = (*len > 0);
103 BufferInput(false);
104 SignalConnectRequest(this, dest_addr);
105 if (remainder) {
106 SignalReadEvent(this);
107 }
108 }
109
110 };
111
112 class NATProxyServer : public ProxyServer {
113 public:
114 NATProxyServer(SocketFactory* int_factory, const SocketAddress& int_addr,
115 SocketFactory* ext_factory, const SocketAddress& ext_ip)
116 : ProxyServer(int_factory, int_addr, ext_factory, ext_ip) {
117 }
118
119 protected:
120 AsyncProxyServerSocket* WrapSocket(AsyncSocket* socket) override {
121 return new NATProxyServerSocket(socket);
122 }
123 };
124
66 NATServer::NATServer( 125 NATServer::NATServer(
67 NATType type, SocketFactory* internal, const SocketAddress& internal_addr, 126 NATType type, SocketFactory* internal,
127 const SocketAddress& internal_udp_addr,
128 const SocketAddress& internal_tcp_addr,
68 SocketFactory* external, const SocketAddress& external_ip) 129 SocketFactory* external, const SocketAddress& external_ip)
69 : external_(external), external_ip_(external_ip.ipaddr(), 0) { 130 : external_(external), external_ip_(external_ip.ipaddr(), 0) {
70 nat_ = NAT::Create(type); 131 nat_ = NAT::Create(type);
71 132
72 server_socket_ = AsyncUDPSocket::Create(internal, internal_addr); 133 udp_server_socket_ = AsyncUDPSocket::Create(internal, internal_udp_addr);
73 server_socket_->SignalReadPacket.connect(this, &NATServer::OnInternalPacket); 134 udp_server_socket_->SignalReadPacket.connect(this,
135 &NATServer::OnInternalUDPPacket);
136 tcp_proxy_server_ = new NATProxyServer(internal, internal_tcp_addr, external,
137 external_ip);
74 138
75 int_map_ = new InternalMap(RouteCmp(nat_)); 139 int_map_ = new InternalMap(RouteCmp(nat_));
76 ext_map_ = new ExternalMap(); 140 ext_map_ = new ExternalMap();
77 } 141 }
78 142
79 NATServer::~NATServer() { 143 NATServer::~NATServer() {
80 for (InternalMap::iterator iter = int_map_->begin(); 144 for (InternalMap::iterator iter = int_map_->begin();
81 iter != int_map_->end(); 145 iter != int_map_->end();
82 iter++) 146 iter++)
83 delete iter->second; 147 delete iter->second;
84 148
85 delete nat_; 149 delete nat_;
86 delete server_socket_; 150 delete udp_server_socket_;
151 delete tcp_proxy_server_;
87 delete int_map_; 152 delete int_map_;
88 delete ext_map_; 153 delete ext_map_;
89 } 154 }
90 155
91 void NATServer::OnInternalPacket( 156 void NATServer::OnInternalUDPPacket(
92 AsyncPacketSocket* socket, const char* buf, size_t size, 157 AsyncPacketSocket* socket, const char* buf, size_t size,
93 const SocketAddress& addr, const PacketTime& packet_time) { 158 const SocketAddress& addr, const PacketTime& packet_time) {
94
95 // Read the intended destination from the wire. 159 // Read the intended destination from the wire.
96 SocketAddress dest_addr; 160 SocketAddress dest_addr;
97 size_t length = UnpackAddressFromNAT(buf, size, &dest_addr); 161 size_t length = UnpackAddressFromNAT(buf, size, &dest_addr);
98 162
99 // Find the translation for these addresses (allocating one if necessary). 163 // Find the translation for these addresses (allocating one if necessary).
100 SocketAddressPair route(addr, dest_addr); 164 SocketAddressPair route(addr, dest_addr);
101 InternalMap::iterator iter = int_map_->find(route); 165 InternalMap::iterator iter = int_map_->find(route);
102 if (iter == int_map_->end()) { 166 if (iter == int_map_->end()) {
103 Translate(route); 167 Translate(route);
104 iter = int_map_->find(route); 168 iter = int_map_->find(route);
105 } 169 }
106 ASSERT(iter != int_map_->end()); 170 ASSERT(iter != int_map_->end());
107 171
108 // Allow the destination to send packets back to the source. 172 // Allow the destination to send packets back to the source.
109 iter->second->WhitelistInsert(dest_addr); 173 iter->second->WhitelistInsert(dest_addr);
110 174
111 // Send the packet to its intended destination. 175 // Send the packet to its intended destination.
112 rtc::PacketOptions options; 176 rtc::PacketOptions options;
113 iter->second->socket->SendTo(buf + length, size - length, dest_addr, options); 177 iter->second->socket->SendTo(buf + length, size - length, dest_addr, options);
114 } 178 }
115 179
116 void NATServer::OnExternalPacket( 180 void NATServer::OnExternalUDPPacket(
117 AsyncPacketSocket* socket, const char* buf, size_t size, 181 AsyncPacketSocket* socket, const char* buf, size_t size,
118 const SocketAddress& remote_addr, const PacketTime& packet_time) { 182 const SocketAddress& remote_addr, const PacketTime& packet_time) {
119
120 SocketAddress local_addr = socket->GetLocalAddress(); 183 SocketAddress local_addr = socket->GetLocalAddress();
121 184
122 // Find the translation for this addresses. 185 // Find the translation for this addresses.
123 ExternalMap::iterator iter = ext_map_->find(local_addr); 186 ExternalMap::iterator iter = ext_map_->find(local_addr);
124 ASSERT(iter != ext_map_->end()); 187 ASSERT(iter != ext_map_->end());
125 188
126 // Allow the NAT to reject this packet. 189 // Allow the NAT to reject this packet.
127 if (ShouldFilterOut(iter->second, remote_addr)) { 190 if (ShouldFilterOut(iter->second, remote_addr)) {
128 LOG(LS_INFO) << "Packet from " << remote_addr.ToSensitiveString() 191 LOG(LS_INFO) << "Packet from " << remote_addr.ToSensitiveString()
129 << " was filtered out by the NAT."; 192 << " was filtered out by the NAT.";
130 return; 193 return;
131 } 194 }
132 195
133 // Forward this packet to the internal address. 196 // Forward this packet to the internal address.
134 // First prepend the address in a quasi-STUN format. 197 // First prepend the address in a quasi-STUN format.
135 scoped_ptr<char[]> real_buf(new char[size + kNATEncodedIPv6AddressSize]); 198 scoped_ptr<char[]> real_buf(new char[size + kNATEncodedIPv6AddressSize]);
136 size_t addrlength = PackAddressForNAT(real_buf.get(), 199 size_t addrlength = PackAddressForNAT(real_buf.get(),
137 size + kNATEncodedIPv6AddressSize, 200 size + kNATEncodedIPv6AddressSize,
138 remote_addr); 201 remote_addr);
139 // Copy the data part after the address. 202 // Copy the data part after the address.
140 rtc::PacketOptions options; 203 rtc::PacketOptions options;
141 memcpy(real_buf.get() + addrlength, buf, size); 204 memcpy(real_buf.get() + addrlength, buf, size);
142 server_socket_->SendTo(real_buf.get(), size + addrlength, 205 udp_server_socket_->SendTo(real_buf.get(), size + addrlength,
143 iter->second->route.source(), options); 206 iter->second->route.source(), options);
144 } 207 }
145 208
146 void NATServer::Translate(const SocketAddressPair& route) { 209 void NATServer::Translate(const SocketAddressPair& route) {
147 AsyncUDPSocket* socket = AsyncUDPSocket::Create(external_, external_ip_); 210 AsyncUDPSocket* socket = AsyncUDPSocket::Create(external_, external_ip_);
148 211
149 if (!socket) { 212 if (!socket) {
150 LOG(LS_ERROR) << "Couldn't find a free port!"; 213 LOG(LS_ERROR) << "Couldn't find a free port!";
151 return; 214 return;
152 } 215 }
153 216
154 TransEntry* entry = new TransEntry(route, socket, nat_); 217 TransEntry* entry = new TransEntry(route, socket, nat_);
155 (*int_map_)[route] = entry; 218 (*int_map_)[route] = entry;
156 (*ext_map_)[socket->GetLocalAddress()] = entry; 219 (*ext_map_)[socket->GetLocalAddress()] = entry;
157 socket->SignalReadPacket.connect(this, &NATServer::OnExternalPacket); 220 socket->SignalReadPacket.connect(this, &NATServer::OnExternalUDPPacket);
158 } 221 }
159 222
160 bool NATServer::ShouldFilterOut(TransEntry* entry, 223 bool NATServer::ShouldFilterOut(TransEntry* entry,
161 const SocketAddress& ext_addr) { 224 const SocketAddress& ext_addr) {
162 return entry->WhitelistContains(ext_addr); 225 return entry->WhitelistContains(ext_addr);
163 } 226 }
164 227
165 NATServer::TransEntry::TransEntry( 228 NATServer::TransEntry::TransEntry(
166 const SocketAddressPair& r, AsyncUDPSocket* s, NAT* nat) 229 const SocketAddressPair& r, AsyncUDPSocket* s, NAT* nat)
167 : route(r), socket(s) { 230 : route(r), socket(s) {
168 whitelist = new AddressSet(AddrCmp(nat)); 231 whitelist = new AddressSet(AddrCmp(nat));
169 } 232 }
170 233
171 NATServer::TransEntry::~TransEntry() { 234 NATServer::TransEntry::~TransEntry() {
172 delete whitelist; 235 delete whitelist;
173 delete socket; 236 delete socket;
174 } 237 }
175 238
176 void NATServer::TransEntry::WhitelistInsert(const SocketAddress& addr) { 239 void NATServer::TransEntry::WhitelistInsert(const SocketAddress& addr) {
177 CritScope cs(&crit_); 240 CritScope cs(&crit_);
178 whitelist->insert(addr); 241 whitelist->insert(addr);
179 } 242 }
180 243
181 bool NATServer::TransEntry::WhitelistContains(const SocketAddress& ext_addr) { 244 bool NATServer::TransEntry::WhitelistContains(const SocketAddress& ext_addr) {
182 CritScope cs(&crit_); 245 CritScope cs(&crit_);
183 return whitelist->find(ext_addr) == whitelist->end(); 246 return whitelist->find(ext_addr) == whitelist->end();
184 } 247 }
185 248
186 } // namespace rtc 249 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/natserver.h ('k') | webrtc/base/natsocketfactory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698