OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/udp/udp_client_socket.h" | |
6 | |
7 #include "net/base/net_errors.h" | |
8 | |
9 namespace net { | |
10 | |
11 UDPClientSocket::UDPClientSocket(DatagramSocket::BindType bind_type, | |
12 const RandIntCallback& rand_int_cb, | |
13 net::NetLog* net_log, | |
14 const net::NetLogSource& source) | |
15 : socket_(bind_type, rand_int_cb, net_log, source), | |
16 network_(NetworkChangeNotifier::kInvalidNetworkHandle) {} | |
17 | |
18 UDPClientSocket::~UDPClientSocket() { | |
19 } | |
20 | |
21 int UDPClientSocket::Connect(const IPEndPoint& address) { | |
22 int rv = socket_.Open(address.GetFamily()); | |
23 if (rv != OK) | |
24 return rv; | |
25 return socket_.Connect(address); | |
26 } | |
27 | |
28 int UDPClientSocket::ConnectUsingNetwork( | |
29 NetworkChangeNotifier::NetworkHandle network, | |
30 const IPEndPoint& address) { | |
31 if (!NetworkChangeNotifier::AreNetworkHandlesSupported()) | |
32 return ERR_NOT_IMPLEMENTED; | |
33 int rv = socket_.Open(address.GetFamily()); | |
34 if (rv != OK) | |
35 return rv; | |
36 rv = socket_.BindToNetwork(network); | |
37 if (rv != OK) | |
38 return rv; | |
39 network_ = network; | |
40 return socket_.Connect(address); | |
41 } | |
42 | |
43 int UDPClientSocket::ConnectUsingDefaultNetwork(const IPEndPoint& address) { | |
44 if (!NetworkChangeNotifier::AreNetworkHandlesSupported()) | |
45 return ERR_NOT_IMPLEMENTED; | |
46 int rv; | |
47 rv = socket_.Open(address.GetFamily()); | |
48 if (rv != OK) | |
49 return rv; | |
50 // Calling connect() will bind a socket to the default network, however there | |
51 // is no way to determine what network the socket got bound to. The | |
52 // alternative is to query what the default network is and bind the socket to | |
53 // that network explicitly, however this is racy because the default network | |
54 // can change in between when we query it and when we bind to it. This is | |
55 // rare but should be accounted for. Since changes of the default network | |
56 // should not come in quick succession, we can simply try again. | |
57 NetworkChangeNotifier::NetworkHandle network; | |
58 for (int attempt = 0; attempt < 2; attempt++) { | |
59 network = NetworkChangeNotifier::GetDefaultNetwork(); | |
60 if (network == NetworkChangeNotifier::kInvalidNetworkHandle) | |
61 return ERR_INTERNET_DISCONNECTED; | |
62 rv = socket_.BindToNetwork(network); | |
63 // |network| may have disconnected between the call to GetDefaultNetwork() | |
64 // and the call to BindToNetwork(). Loop only if this is the case (|rv| will | |
65 // be ERR_NETWORK_CHANGED). | |
66 if (rv != ERR_NETWORK_CHANGED) | |
67 break; | |
68 } | |
69 if (rv != OK) | |
70 return rv; | |
71 network_ = network; | |
72 return socket_.Connect(address); | |
73 } | |
74 | |
75 NetworkChangeNotifier::NetworkHandle UDPClientSocket::GetBoundNetwork() const { | |
76 return network_; | |
77 } | |
78 | |
79 int UDPClientSocket::Read(IOBuffer* buf, | |
80 int buf_len, | |
81 const CompletionCallback& callback) { | |
82 return socket_.Read(buf, buf_len, callback); | |
83 } | |
84 | |
85 int UDPClientSocket::Write(IOBuffer* buf, | |
86 int buf_len, | |
87 const CompletionCallback& callback) { | |
88 return socket_.Write(buf, buf_len, callback); | |
89 } | |
90 | |
91 void UDPClientSocket::Close() { | |
92 socket_.Close(); | |
93 } | |
94 | |
95 int UDPClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
96 return socket_.GetPeerAddress(address); | |
97 } | |
98 | |
99 int UDPClientSocket::GetLocalAddress(IPEndPoint* address) const { | |
100 return socket_.GetLocalAddress(address); | |
101 } | |
102 | |
103 int UDPClientSocket::SetReceiveBufferSize(int32_t size) { | |
104 return socket_.SetReceiveBufferSize(size); | |
105 } | |
106 | |
107 int UDPClientSocket::SetSendBufferSize(int32_t size) { | |
108 return socket_.SetSendBufferSize(size); | |
109 } | |
110 | |
111 int UDPClientSocket::SetDoNotFragment() { | |
112 return socket_.SetDoNotFragment(); | |
113 } | |
114 | |
115 const NetLogWithSource& UDPClientSocket::NetLog() const { | |
116 return socket_.NetLog(); | |
117 } | |
118 | |
119 void UDPClientSocket::UseNonBlockingIO() { | |
120 #if defined(OS_WIN) | |
121 socket_.UseNonBlockingIO(); | |
122 #endif | |
123 } | |
124 | |
125 } // namespace net | |
OLD | NEW |