OLD | NEW |
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 #include "webrtc/base/physicalsocketserver.h" | 10 #include "webrtc/base/physicalsocketserver.h" |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 if (result >= 0) { | 183 if (result >= 0) { |
184 SocketAddressFromSockAddrStorage(addr_storage, &address); | 184 SocketAddressFromSockAddrStorage(addr_storage, &address); |
185 } else { | 185 } else { |
186 LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket=" | 186 LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket=" |
187 << s_; | 187 << s_; |
188 } | 188 } |
189 return address; | 189 return address; |
190 } | 190 } |
191 | 191 |
192 int PhysicalSocket::Bind(const SocketAddress& bind_addr) { | 192 int PhysicalSocket::Bind(const SocketAddress& bind_addr) { |
| 193 SocketAddress copied_bind_addr = bind_addr; |
| 194 // If a network binder is available, use it to bind a socket to an interface |
| 195 // instead of bind(), since this is more reliable on an OS with a weak host |
| 196 // model. |
| 197 if (ss_->network_binder()) { |
| 198 NetworkBindingResult result = |
| 199 ss_->network_binder()->BindSocketToNetwork(s_, bind_addr.ipaddr()); |
| 200 if (result == NetworkBindingResult::SUCCESS) { |
| 201 // Since the network binder handled binding the socket to the desired |
| 202 // network interface, we don't need to (and shouldn't) include an IP in |
| 203 // the bind() call; bind() just needs to assign a port. |
| 204 copied_bind_addr.SetIP(GetAnyIP(copied_bind_addr.ipaddr().family())); |
| 205 } else if (result == NetworkBindingResult::NOT_IMPLEMENTED) { |
| 206 LOG(LS_INFO) << "Can't bind socket to network because " |
| 207 "network binding is not implemented for this OS."; |
| 208 } else { |
| 209 if (bind_addr.IsLoopbackIP()) { |
| 210 // If we couldn't bind to a loopback IP (which should only happen in |
| 211 // test scenarios), continue on. This may be expected behavior. |
| 212 LOG(LS_VERBOSE) << "Binding socket to loopback address " |
| 213 << bind_addr.ipaddr().ToString() |
| 214 << " failed; result: " << static_cast<int>(result); |
| 215 } else { |
| 216 LOG(LS_WARNING) << "Binding socket to network address " |
| 217 << bind_addr.ipaddr().ToString() |
| 218 << " failed; result: " << static_cast<int>(result); |
| 219 // If a network binding was attempted and failed, we should stop here |
| 220 // and not try to use the socket. Otherwise, we may end up sending |
| 221 // packets with an invalid source address. |
| 222 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7026 |
| 223 return -1; |
| 224 } |
| 225 } |
| 226 } |
193 sockaddr_storage addr_storage; | 227 sockaddr_storage addr_storage; |
194 size_t len = bind_addr.ToSockAddrStorage(&addr_storage); | 228 size_t len = copied_bind_addr.ToSockAddrStorage(&addr_storage); |
195 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); | 229 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); |
196 int err = ::bind(s_, addr, static_cast<int>(len)); | 230 int err = ::bind(s_, addr, static_cast<int>(len)); |
197 UpdateLastError(); | 231 UpdateLastError(); |
198 #if !defined(NDEBUG) | 232 #if !defined(NDEBUG) |
199 if (0 == err) { | 233 if (0 == err) { |
200 dbg_addr_ = "Bound @ "; | 234 dbg_addr_ = "Bound @ "; |
201 dbg_addr_.append(GetLocalAddress().ToString()); | 235 dbg_addr_.append(GetLocalAddress().ToString()); |
202 } | 236 } |
203 #endif | 237 #endif |
204 if (ss_->network_binder()) { | |
205 int result = | |
206 ss_->network_binder()->BindSocketToNetwork(s_, bind_addr.ipaddr()); | |
207 if (result < 0) { | |
208 LOG(LS_INFO) << "Binding socket to network address " | |
209 << bind_addr.ipaddr().ToString() << " result " << result; | |
210 } | |
211 } | |
212 return err; | 238 return err; |
213 } | 239 } |
214 | 240 |
215 int PhysicalSocket::Connect(const SocketAddress& addr) { | 241 int PhysicalSocket::Connect(const SocketAddress& addr) { |
216 // TODO(pthatcher): Implicit creation is required to reconnect... | 242 // TODO(pthatcher): Implicit creation is required to reconnect... |
217 // ...but should we make it more explicit? | 243 // ...but should we make it more explicit? |
218 if (state_ != CS_CLOSED) { | 244 if (state_ != CS_CLOSED) { |
219 SetError(EALREADY); | 245 SetError(EALREADY); |
220 return SOCKET_ERROR; | 246 return SOCKET_ERROR; |
221 } | 247 } |
(...skipping 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1611 break; | 1637 break; |
1612 } | 1638 } |
1613 } | 1639 } |
1614 | 1640 |
1615 // Done | 1641 // Done |
1616 return true; | 1642 return true; |
1617 } | 1643 } |
1618 #endif // WEBRTC_WIN | 1644 #endif // WEBRTC_WIN |
1619 | 1645 |
1620 } // namespace rtc | 1646 } // namespace rtc |
OLD | NEW |