OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/quic/quic_client.h" | 5 #include "net/tools/quic/quic_client.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <netinet/in.h> | 8 #include <netinet/in.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <sys/epoll.h> | 10 #include <sys/epoll.h> |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 initialized_(false), | 65 initialized_(false), |
66 packets_dropped_(0), | 66 packets_dropped_(0), |
67 overflow_supported_(false), | 67 overflow_supported_(false), |
68 supported_versions_(supported_versions), | 68 supported_versions_(supported_versions), |
69 print_response_(false), | 69 print_response_(false), |
70 initial_flow_control_window_(initial_flow_control_window) { | 70 initial_flow_control_window_(initial_flow_control_window) { |
71 } | 71 } |
72 | 72 |
73 QuicClient::~QuicClient() { | 73 QuicClient::~QuicClient() { |
74 if (connected()) { | 74 if (connected()) { |
75 session()->connection()->SendConnectionClosePacket( | 75 session()->connection()->SendConnectionClosePacket(QUIC_PEER_GOING_AWAY, |
76 QUIC_PEER_GOING_AWAY, ""); | 76 ""); |
77 } | 77 } |
78 } | 78 } |
79 | 79 |
80 bool QuicClient::Initialize() { | 80 bool QuicClient::Initialize() { |
81 DCHECK(!initialized_); | 81 DCHECK(!initialized_); |
82 | 82 |
83 epoll_server_.set_timeout_in_us(50 * 1000); | 83 epoll_server_.set_timeout_in_us(50 * 1000); |
84 crypto_config_.SetDefaults(); | 84 crypto_config_.SetDefaults(); |
85 | 85 |
86 int address_family = server_address_.GetSockAddrFamily(); | 86 int address_family = server_address_.GetSockAddrFamily(); |
87 fd_ = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP); | 87 fd_ = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP); |
88 if (fd_ < 0) { | 88 if (fd_ < 0) { |
89 LOG(ERROR) << "CreateSocket() failed: " << strerror(errno); | 89 LOG(ERROR) << "CreateSocket() failed: " << strerror(errno); |
90 return false; | 90 return false; |
91 } | 91 } |
92 | 92 |
93 int get_overflow = 1; | 93 int get_overflow = 1; |
94 int rc = setsockopt(fd_, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow, | 94 int rc = setsockopt( |
95 sizeof(get_overflow)); | 95 fd_, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow, sizeof(get_overflow)); |
96 if (rc < 0) { | 96 if (rc < 0) { |
97 DLOG(WARNING) << "Socket overflow detection not supported"; | 97 DLOG(WARNING) << "Socket overflow detection not supported"; |
98 } else { | 98 } else { |
99 overflow_supported_ = true; | 99 overflow_supported_ = true; |
100 } | 100 } |
101 | 101 |
102 if (!QuicSocketUtils::SetReceiveBufferSize(fd_, | 102 if (!QuicSocketUtils::SetReceiveBufferSize(fd_, |
103 TcpReceiver::kReceiveWindowTCP)) { | 103 TcpReceiver::kReceiveWindowTCP)) { |
104 return false; | 104 return false; |
105 } | 105 } |
106 | 106 |
107 if (!QuicSocketUtils::SetSendBufferSize(fd_, | 107 if (!QuicSocketUtils::SetSendBufferSize(fd_, |
108 TcpReceiver::kReceiveWindowTCP)) { | 108 TcpReceiver::kReceiveWindowTCP)) { |
109 return false; | 109 return false; |
110 } | 110 } |
111 | 111 |
112 int get_local_ip = 1; | 112 int get_local_ip = 1; |
113 if (address_family == AF_INET) { | 113 if (address_family == AF_INET) { |
114 rc = setsockopt(fd_, IPPROTO_IP, IP_PKTINFO, | 114 rc = setsockopt( |
115 &get_local_ip, sizeof(get_local_ip)); | 115 fd_, IPPROTO_IP, IP_PKTINFO, &get_local_ip, sizeof(get_local_ip)); |
116 } else { | 116 } else { |
117 rc = setsockopt(fd_, IPPROTO_IPV6, IPV6_RECVPKTINFO, | 117 rc = setsockopt(fd_, |
118 &get_local_ip, sizeof(get_local_ip)); | 118 IPPROTO_IPV6, |
| 119 IPV6_RECVPKTINFO, |
| 120 &get_local_ip, |
| 121 sizeof(get_local_ip)); |
119 } | 122 } |
120 | 123 |
121 if (rc < 0) { | 124 if (rc < 0) { |
122 LOG(ERROR) << "IP detection not supported" << strerror(errno); | 125 LOG(ERROR) << "IP detection not supported" << strerror(errno); |
123 return false; | 126 return false; |
124 } | 127 } |
125 | 128 |
126 if (bind_to_address_.size() != 0) { | 129 if (bind_to_address_.size() != 0) { |
127 client_address_ = IPEndPoint(bind_to_address_, local_port_); | 130 client_address_ = IPEndPoint(bind_to_address_, local_port_); |
128 } else if (address_family == AF_INET) { | 131 } else if (address_family == AF_INET) { |
129 IPAddressNumber any4; | 132 IPAddressNumber any4; |
130 CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &any4)); | 133 CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &any4)); |
131 client_address_ = IPEndPoint(any4, local_port_); | 134 client_address_ = IPEndPoint(any4, local_port_); |
132 } else { | 135 } else { |
133 IPAddressNumber any6; | 136 IPAddressNumber any6; |
134 CHECK(net::ParseIPLiteralToNumber("::", &any6)); | 137 CHECK(net::ParseIPLiteralToNumber("::", &any6)); |
135 client_address_ = IPEndPoint(any6, local_port_); | 138 client_address_ = IPEndPoint(any6, local_port_); |
136 } | 139 } |
137 | 140 |
138 sockaddr_storage raw_addr; | 141 sockaddr_storage raw_addr; |
139 socklen_t raw_addr_len = sizeof(raw_addr); | 142 socklen_t raw_addr_len = sizeof(raw_addr); |
140 CHECK(client_address_.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr), | 143 CHECK(client_address_.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr), |
141 &raw_addr_len)); | 144 &raw_addr_len)); |
142 rc = bind(fd_, | 145 rc = |
143 reinterpret_cast<const sockaddr*>(&raw_addr), | 146 bind(fd_, reinterpret_cast<const sockaddr*>(&raw_addr), sizeof(raw_addr)); |
144 sizeof(raw_addr)); | |
145 if (rc < 0) { | 147 if (rc < 0) { |
146 LOG(ERROR) << "Bind failed: " << strerror(errno); | 148 LOG(ERROR) << "Bind failed: " << strerror(errno); |
147 return false; | 149 return false; |
148 } | 150 } |
149 | 151 |
150 SockaddrStorage storage; | 152 SockaddrStorage storage; |
151 if (getsockname(fd_, storage.addr, &storage.addr_len) != 0 || | 153 if (getsockname(fd_, storage.addr, &storage.addr_len) != 0 || |
152 !client_address_.FromSockAddr(storage.addr, storage.addr_len)) { | 154 !client_address_.FromSockAddr(storage.addr, storage.addr_len)) { |
153 LOG(ERROR) << "Unable to get self address. Error: " << strerror(errno); | 155 LOG(ERROR) << "Unable to get self address. Error: " << strerror(errno); |
154 } | 156 } |
(...skipping 15 matching lines...) Expand all Loading... |
170 | 172 |
171 bool QuicClient::StartConnect() { | 173 bool QuicClient::StartConnect() { |
172 DCHECK(initialized_); | 174 DCHECK(initialized_); |
173 DCHECK(!connected()); | 175 DCHECK(!connected()); |
174 | 176 |
175 QuicPacketWriter* writer = CreateQuicPacketWriter(); | 177 QuicPacketWriter* writer = CreateQuicPacketWriter(); |
176 if (writer_.get() != writer) { | 178 if (writer_.get() != writer) { |
177 writer_.reset(writer); | 179 writer_.reset(writer); |
178 } | 180 } |
179 | 181 |
180 session_.reset(new QuicClientSession( | 182 session_.reset( |
181 server_id_, | 183 new QuicClientSession(server_id_, |
182 config_, | 184 config_, |
183 new QuicConnection(GenerateConnectionId(), server_address_, helper_.get(), | 185 new QuicConnection(GenerateConnectionId(), |
184 writer_.get(), false, supported_versions_, | 186 server_address_, |
185 initial_flow_control_window_), | 187 helper_.get(), |
186 &crypto_config_)); | 188 writer_.get(), |
| 189 false, |
| 190 supported_versions_, |
| 191 initial_flow_control_window_), |
| 192 &crypto_config_)); |
187 return session_->CryptoConnect(); | 193 return session_->CryptoConnect(); |
188 } | 194 } |
189 | 195 |
190 bool QuicClient::EncryptionBeingEstablished() { | 196 bool QuicClient::EncryptionBeingEstablished() { |
191 return !session_->IsEncryptionEstablished() && | 197 return !session_->IsEncryptionEstablished() && |
192 session_->connection()->connected(); | 198 session_->connection()->connected(); |
193 } | 199 } |
194 | 200 |
195 void QuicClient::Disconnect() { | 201 void QuicClient::Disconnect() { |
196 DCHECK(initialized_); | 202 DCHECK(initialized_); |
197 | 203 |
198 if (connected()) { | 204 if (connected()) { |
199 session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); | 205 session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); |
200 } | 206 } |
201 epoll_server_.UnregisterFD(fd_); | 207 epoll_server_.UnregisterFD(fd_); |
202 close(fd_); | 208 close(fd_); |
203 fd_ = -1; | 209 fd_ = -1; |
204 initialized_ = false; | 210 initialized_ = false; |
205 } | 211 } |
206 | 212 |
207 void QuicClient::SendRequestsAndWaitForResponse( | 213 void QuicClient::SendRequestsAndWaitForResponse( |
208 const CommandLine::StringVector& args) { | 214 const CommandLine::StringVector& args) { |
209 for (size_t i = 0; i < args.size(); ++i) { | 215 for (size_t i = 0; i < args.size(); ++i) { |
210 BalsaHeaders headers; | 216 BalsaHeaders headers; |
211 headers.SetRequestFirstlineFromStringPieces("GET", args[i], "HTTP/1.1"); | 217 headers.SetRequestFirstlineFromStringPieces("GET", args[i], "HTTP/1.1"); |
212 QuicSpdyClientStream* stream = CreateReliableClientStream(); | 218 QuicSpdyClientStream* stream = CreateReliableClientStream(); |
213 stream->SendRequest(headers, "", true); | 219 stream->SendRequest(headers, "", true); |
214 stream->set_visitor(this); | 220 stream->set_visitor(this); |
215 } | 221 } |
216 | 222 |
217 while (WaitForEvents()) { } | 223 while (WaitForEvents()) { |
| 224 } |
218 } | 225 } |
219 | 226 |
220 QuicSpdyClientStream* QuicClient::CreateReliableClientStream() { | 227 QuicSpdyClientStream* QuicClient::CreateReliableClientStream() { |
221 if (!connected()) { | 228 if (!connected()) { |
222 return NULL; | 229 return NULL; |
223 } | 230 } |
224 | 231 |
225 return session_->CreateOutgoingDataStream(); | 232 return session_->CreateOutgoingDataStream(); |
226 } | 233 } |
227 | 234 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 } | 280 } |
274 | 281 |
275 if (!print_response_) { | 282 if (!print_response_) { |
276 return; | 283 return; |
277 } | 284 } |
278 | 285 |
279 const BalsaHeaders& headers = client_stream->headers(); | 286 const BalsaHeaders& headers = client_stream->headers(); |
280 printf("%s\n", headers.first_line().as_string().c_str()); | 287 printf("%s\n", headers.first_line().as_string().c_str()); |
281 for (BalsaHeaders::const_header_lines_iterator i = | 288 for (BalsaHeaders::const_header_lines_iterator i = |
282 headers.header_lines_begin(); | 289 headers.header_lines_begin(); |
283 i != headers.header_lines_end(); ++i) { | 290 i != headers.header_lines_end(); |
284 printf("%s: %s\n", i->first.as_string().c_str(), | 291 ++i) { |
| 292 printf("%s: %s\n", |
| 293 i->first.as_string().c_str(), |
285 i->second.as_string().c_str()); | 294 i->second.as_string().c_str()); |
286 } | 295 } |
287 printf("%s\n", client_stream->data().c_str()); | 296 printf("%s\n", client_stream->data().c_str()); |
288 } | 297 } |
289 | 298 |
290 QuicPacketCreator::Options* QuicClient::options() { | 299 QuicPacketCreator::Options* QuicClient::options() { |
291 if (session() == NULL) { | 300 if (session() == NULL) { |
292 return NULL; | 301 return NULL; |
293 } | 302 } |
294 return session_->options(); | 303 return session_->options(); |
295 } | 304 } |
296 | 305 |
297 bool QuicClient::connected() const { | 306 bool QuicClient::connected() const { |
298 return session_.get() && session_->connection() && | 307 return session_.get() && session_->connection() && |
299 session_->connection()->connected(); | 308 session_->connection()->connected(); |
300 } | 309 } |
301 | 310 |
302 QuicConnectionId QuicClient::GenerateConnectionId() { | 311 QuicConnectionId QuicClient::GenerateConnectionId() { |
303 return QuicRandom::GetInstance()->RandUint64(); | 312 return QuicRandom::GetInstance()->RandUint64(); |
304 } | 313 } |
305 | 314 |
306 QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() { | 315 QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() { |
307 return new QuicEpollConnectionHelper(&epoll_server_); | 316 return new QuicEpollConnectionHelper(&epoll_server_); |
308 } | 317 } |
309 | 318 |
310 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { | 319 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { |
311 return new QuicDefaultPacketWriter(fd_); | 320 return new QuicDefaultPacketWriter(fd_); |
312 } | 321 } |
313 | 322 |
314 int QuicClient::ReadPacket(char* buffer, | 323 int QuicClient::ReadPacket(char* buffer, |
315 int buffer_len, | 324 int buffer_len, |
316 IPEndPoint* server_address, | 325 IPEndPoint* server_address, |
317 IPAddressNumber* client_ip) { | 326 IPAddressNumber* client_ip) { |
318 return QuicSocketUtils::ReadPacket( | 327 return QuicSocketUtils::ReadPacket( |
319 fd_, buffer, buffer_len, overflow_supported_ ? &packets_dropped_ : NULL, | 328 fd_, |
320 client_ip, server_address); | 329 buffer, |
| 330 buffer_len, |
| 331 overflow_supported_ ? &packets_dropped_ : NULL, |
| 332 client_ip, |
| 333 server_address); |
321 } | 334 } |
322 | 335 |
323 bool QuicClient::ReadAndProcessPacket() { | 336 bool QuicClient::ReadAndProcessPacket() { |
324 // Allocate some extra space so we can send an error if the server goes over | 337 // Allocate some extra space so we can send an error if the server goes over |
325 // the limit. | 338 // the limit. |
326 char buf[2 * kMaxPacketSize]; | 339 char buf[2 * kMaxPacketSize]; |
327 | 340 |
328 IPEndPoint server_address; | 341 IPEndPoint server_address; |
329 IPAddressNumber client_ip; | 342 IPAddressNumber client_ip; |
330 | 343 |
331 int bytes_read = ReadPacket(buf, arraysize(buf), &server_address, &client_ip); | 344 int bytes_read = ReadPacket(buf, arraysize(buf), &server_address, &client_ip); |
332 | 345 |
333 if (bytes_read < 0) { | 346 if (bytes_read < 0) { |
334 return false; | 347 return false; |
335 } | 348 } |
336 | 349 |
337 QuicEncryptedPacket packet(buf, bytes_read, false); | 350 QuicEncryptedPacket packet(buf, bytes_read, false); |
338 | 351 |
339 IPEndPoint client_address(client_ip, client_address_.port()); | 352 IPEndPoint client_address(client_ip, client_address_.port()); |
340 session_->connection()->ProcessUdpPacket( | 353 session_->connection()->ProcessUdpPacket( |
341 client_address, server_address, packet); | 354 client_address, server_address, packet); |
342 return true; | 355 return true; |
343 } | 356 } |
344 | 357 |
345 } // namespace tools | 358 } // namespace tools |
346 } // namespace net | 359 } // namespace net |
OLD | NEW |