Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 <dirent.h> | 5 #include <dirent.h> |
| 6 #include <netinet/tcp.h> // For TCP_NODELAY | 6 #include <netinet/tcp.h> // For TCP_NODELAY |
| 7 #include <sys/socket.h> | 7 #include <sys/socket.h> |
| 8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 #include <sys/file.h> | 9 #include <sys/file.h> |
| 10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 PrintSslError(); | 272 PrintSslError(); |
| 273 | 273 |
| 274 SSL_set_accept_state(ssl); | 274 SSL_set_accept_state(ssl); |
| 275 PrintSslError(); | 275 PrintSslError(); |
| 276 | 276 |
| 277 return ssl; | 277 return ssl; |
| 278 } | 278 } |
| 279 | 279 |
| 280 //////////////////////////////////////////////////////////////////////////////// | 280 //////////////////////////////////////////////////////////////////////////////// |
| 281 | 281 |
| 282 const int kMSS = 1400; // Linux default | 282 const int kMSS = 1460; |
| 283 const int kSSLOverhead = 33; | 283 const int kSSLOverhead = 25; |
| 284 const int kSpdyOverhead = SpdyFrame::size(); | 284 const int kSpdyOverhead = SpdyFrame::size(); |
| 285 const int kInitialDataSendersThreshold = (2 * kMSS) - kSpdyOverhead; | 285 const int kInitialDataSendersThreshold = (2 * kMSS) - kSpdyOverhead; |
| 286 const int kSSLSegmentSize = (1 * kMSS) - kSSLOverhead; | 286 const int kSSLSegmentSize = (1 * kMSS) - kSSLOverhead; |
| 287 const int kSpdySegmentSize = kSSLSegmentSize - kSpdyOverhead; | 287 const int kSpdySegmentSize = kSSLSegmentSize - kSpdyOverhead; |
| 288 | 288 |
| 289 //////////////////////////////////////////////////////////////////////////////// | 289 //////////////////////////////////////////////////////////////////////////////// |
| 290 | 290 |
| 291 class DataFrame { | 291 class DataFrame { |
| 292 public: | 292 public: |
| 293 const char* data; | 293 const char* data; |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 802 events_(0), | 802 events_(0), |
| 803 registered_in_epoll_server_(false), | 803 registered_in_epoll_server_(false), |
| 804 initialized_(false), | 804 initialized_(false), |
| 805 protocol_detected_(false), | 805 protocol_detected_(false), |
| 806 connection_complete_(false), | 806 connection_complete_(false), |
| 807 connection_pool_(NULL), | 807 connection_pool_(NULL), |
| 808 epoll_server_(epoll_server), | 808 epoll_server_(epoll_server), |
| 809 ssl_state_(ssl_state), | 809 ssl_state_(ssl_state), |
| 810 memory_cache_(memory_cache), | 810 memory_cache_(memory_cache), |
| 811 acceptor_(acceptor), | 811 acceptor_(acceptor), |
| 812 read_buffer_(4096*10), | 812 read_buffer_(kSpdySegmentSize * 40), |
| 813 sm_spdy_interface_(NULL), | 813 sm_spdy_interface_(NULL), |
| 814 sm_http_interface_(NULL), | 814 sm_http_interface_(NULL), |
| 815 sm_streamer_interface_(NULL), | 815 sm_streamer_interface_(NULL), |
| 816 sm_interface_(NULL), | 816 sm_interface_(NULL), |
| 817 log_prefix_(log_prefix), | 817 log_prefix_(log_prefix), |
| 818 max_bytes_sent_per_dowrite_(4096), | 818 max_bytes_sent_per_dowrite_(4096), |
| 819 ssl_(NULL), | 819 ssl_(NULL), |
| 820 last_read_time_(0) | 820 last_read_time_(0) |
| 821 {} | 821 {} |
| 822 | 822 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 966 | 966 |
| 967 epoll_server_->RegisterFD(fd_, this, EPOLLIN | EPOLLOUT | EPOLLET); | 967 epoll_server_->RegisterFD(fd_, this, EPOLLIN | EPOLLOUT | EPOLLET); |
| 968 | 968 |
| 969 if (use_ssl) { | 969 if (use_ssl) { |
| 970 ssl_ = spdy_new_ssl(ssl_state_->ssl_ctx); | 970 ssl_ = spdy_new_ssl(ssl_state_->ssl_ctx); |
| 971 SSL_set_fd(ssl_, fd_); | 971 SSL_set_fd(ssl_, fd_); |
| 972 PrintSslError(); | 972 PrintSslError(); |
| 973 } | 973 } |
| 974 } | 974 } |
| 975 | 975 |
| 976 void CorkSocket() { | |
| 977 int state = 1; | |
| 978 int rv = setsockopt(fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)); | |
| 979 if (rv < 0) | |
| 980 VLOG(1) << "setsockopt(CORK): " << errno; | |
| 981 } | |
| 982 | |
| 983 void UncorkSocket() { | |
| 984 int state = 0; | |
| 985 int rv = setsockopt(fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)); | |
| 986 if (rv < 0) | |
| 987 VLOG(1) << "setsockopt(CORK): " << errno; | |
| 988 } | |
| 989 | |
| 976 int Send(const char* data, int len, int flags) { | 990 int Send(const char* data, int len, int flags) { |
| 977 ssize_t bytes_written = 0; | 991 int rv; |
| 992 CorkSocket(); | |
|
fenix
2011/01/27 20:34:59
hopefully no ill effects to corking when it is alr
| |
| 978 if (ssl_) { | 993 if (ssl_) { |
| 994 ssize_t bytes_written = 0; | |
| 979 // Write smallish chunks to SSL so that we don't have large | 995 // Write smallish chunks to SSL so that we don't have large |
| 980 // multi-packet TLS records to receive before being able to handle | 996 // multi-packet TLS records to receive before being able to handle |
| 981 // the data. | 997 // the data. We don't have to be too careful here, because our data |
| 998 // frames are already getting chunked appropriately, and those are | |
| 999 // the most likely "big" frames. | |
| 982 while(len > 0) { | 1000 while(len > 0) { |
| 983 const int kMaxTLSRecordSize = 1460; | 1001 const int kMaxTLSRecordSize = 1500; |
| 984 const char* ptr = &(data[bytes_written]); | 1002 const char* ptr = &(data[bytes_written]); |
| 985 int chunksize = std::min(len, kMaxTLSRecordSize); | 1003 int chunksize = std::min(len, kMaxTLSRecordSize); |
| 986 int rv = SSL_write(ssl_, ptr, chunksize); | 1004 rv = SSL_write(ssl_, ptr, chunksize); |
| 1005 VLOG(2) << "SSLWrite(" << chunksize << " bytes): " << rv; | |
| 987 if (rv <= 0) { | 1006 if (rv <= 0) { |
| 988 switch(SSL_get_error(ssl_, rv)) { | 1007 switch(SSL_get_error(ssl_, rv)) { |
| 989 case SSL_ERROR_WANT_READ: | 1008 case SSL_ERROR_WANT_READ: |
| 990 case SSL_ERROR_WANT_WRITE: | 1009 case SSL_ERROR_WANT_WRITE: |
| 991 case SSL_ERROR_WANT_ACCEPT: | 1010 case SSL_ERROR_WANT_ACCEPT: |
| 992 case SSL_ERROR_WANT_CONNECT: | 1011 case SSL_ERROR_WANT_CONNECT: |
| 993 rv = -2; | 1012 rv = -2; |
| 994 break; | 1013 break; |
| 995 default: | 1014 default: |
| 996 PrintSslError(); | 1015 PrintSslError(); |
| 997 break; | 1016 break; |
| 998 } | 1017 } |
| 999 // If we wrote some data, return that count. Otherwise | 1018 break; |
| 1000 // return the stall error. | |
| 1001 return bytes_written > 0 ? bytes_written : rv; | |
| 1002 } | 1019 } |
| 1003 bytes_written += rv; | 1020 bytes_written += rv; |
| 1004 len -= rv; | 1021 len -= rv; |
| 1005 if (rv != chunksize) | 1022 if (rv != chunksize) |
| 1006 break; // If we couldn't write everything, we're implicitly stalled | 1023 break; // If we couldn't write everything, we're implicitly stalled |
| 1007 } | 1024 } |
| 1008 if (!(flags & MSG_MORE)) { | 1025 // If we wrote some data, return that count. Otherwise |
| 1009 int state = 0; | 1026 // return the stall error. |
| 1010 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); | 1027 if (bytes_written > 0) |
| 1011 state = 1; | 1028 rv = bytes_written; |
| 1012 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); | |
| 1013 } | |
| 1014 } else { | 1029 } else { |
| 1015 bytes_written = send(fd_, data, len, flags); | 1030 rv = send(fd_, data, len, flags); |
| 1016 } | 1031 } |
| 1017 return bytes_written; | 1032 if (!(flags & MSG_MORE)) |
| 1033 UncorkSocket(); | |
| 1034 return rv; | |
| 1018 } | 1035 } |
| 1019 | 1036 |
| 1020 // the following are from the EpollCallbackInterface | 1037 // the following are from the EpollCallbackInterface |
| 1021 virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) { | 1038 virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) { |
| 1022 registered_in_epoll_server_ = true; | 1039 registered_in_epoll_server_ = true; |
| 1023 } | 1040 } |
| 1024 virtual void OnModification(int fd, int event_mask) { } | 1041 virtual void OnModification(int fd, int event_mask) { } |
| 1025 virtual void OnEvent(int fd, EpollEvent* event) { | 1042 virtual void OnEvent(int fd, EpollEvent* event) { |
| 1026 events_ |= event->in_events; | 1043 events_ |= event->in_events; |
| 1027 HandleEvents(); | 1044 HandleEvents(); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1177 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1194 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 1178 << (sm_spdy_interface_ ? "Creating" : "Reusing") | 1195 << (sm_spdy_interface_ ? "Creating" : "Reusing") |
| 1179 << " SPDY interface."; | 1196 << " SPDY interface."; |
| 1180 if (!sm_spdy_interface_) | 1197 if (!sm_spdy_interface_) |
| 1181 sm_spdy_interface_ = NewSpdySM(this, NULL, epoll_server_, | 1198 sm_spdy_interface_ = NewSpdySM(this, NULL, epoll_server_, |
| 1182 memory_cache_, acceptor_); | 1199 memory_cache_, acceptor_); |
| 1183 sm_interface_ = sm_spdy_interface_; | 1200 sm_interface_ = sm_spdy_interface_; |
| 1184 } | 1201 } |
| 1185 break; | 1202 break; |
| 1186 } | 1203 } |
| 1204 | |
| 1205 CorkSocket(); | |
| 1187 if (!sm_interface_->PostAcceptHook()) | 1206 if (!sm_interface_->PostAcceptHook()) |
| 1188 return false; | 1207 return false; |
| 1189 | 1208 |
| 1190 return true; | 1209 return true; |
| 1191 } | 1210 } |
| 1192 | 1211 |
| 1193 bool DoRead() { | 1212 bool DoRead() { |
| 1194 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead()"; | 1213 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead()"; |
| 1195 while (!read_buffer_.Full()) { | 1214 while (!read_buffer_.Full()) { |
| 1196 char* bytes; | 1215 char* bytes; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1347 if (sm_interface_ && output_list_.size() < 2) { | 1366 if (sm_interface_ && output_list_.size() < 2) { |
| 1348 sm_interface_->GetOutput(); | 1367 sm_interface_->GetOutput(); |
| 1349 } | 1368 } |
| 1350 DataFrame* data_frame = output_list_.front(); | 1369 DataFrame* data_frame = output_list_.front(); |
| 1351 const char* bytes = data_frame->data; | 1370 const char* bytes = data_frame->data; |
| 1352 int size = data_frame->size; | 1371 int size = data_frame->size; |
| 1353 bytes += data_frame->index; | 1372 bytes += data_frame->index; |
| 1354 size -= data_frame->index; | 1373 size -= data_frame->index; |
| 1355 DCHECK_GE(size, 0); | 1374 DCHECK_GE(size, 0); |
| 1356 if (size <= 0) { | 1375 if (size <= 0) { |
| 1357 // Empty data frame. Indicates end of data from client. | |
| 1358 // Uncork the socket. | |
| 1359 int state = 0; | |
| 1360 VLOG(2) << log_prefix_ << "Empty data frame, uncorking socket."; | |
| 1361 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); | |
| 1362 output_list_.pop_front(); | 1376 output_list_.pop_front(); |
| 1363 delete data_frame; | 1377 delete data_frame; |
| 1364 continue; | 1378 continue; |
| 1365 } | 1379 } |
| 1366 | 1380 |
| 1367 flags = MSG_NOSIGNAL | MSG_DONTWAIT; | 1381 flags = MSG_NOSIGNAL | MSG_DONTWAIT; |
| 1382 // Look for a queue size > 1 because |this| frame is remains on the list | |
| 1383 // until it has finished sending. | |
| 1368 if (output_list_.size() > 1) { | 1384 if (output_list_.size() > 1) { |
| 1369 VLOG(2) << log_prefix_ << "Outlist size: " << output_list_.size() | 1385 VLOG(2) << log_prefix_ << "Outlist size: " << output_list_.size() |
| 1370 << ": Adding MSG_MORE flag"; | 1386 << ": Adding MSG_MORE flag"; |
| 1371 flags |= MSG_MORE; | 1387 flags |= MSG_MORE; |
| 1372 } | 1388 } |
| 1373 VLOG(2) << log_prefix_ << "Attempting to send " << size << " bytes."; | 1389 VLOG(2) << log_prefix_ << "Attempting to send " << size << " bytes."; |
| 1374 ssize_t bytes_written = Send(bytes, size, flags); | 1390 ssize_t bytes_written = Send(bytes, size, flags); |
| 1375 int stored_errno = errno; | 1391 int stored_errno = errno; |
| 1376 if (bytes_written == -1) { | 1392 if (bytes_written == -1) { |
| 1377 switch (stored_errno) { | 1393 switch (stored_errno) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1399 } else if (bytes_written == -2) { | 1415 } else if (bytes_written == -2) { |
| 1400 // -2 handles SSL_ERROR_WANT_* errors | 1416 // -2 handles SSL_ERROR_WANT_* errors |
| 1401 events_ &= ~EPOLLOUT; | 1417 events_ &= ~EPOLLOUT; |
| 1402 goto done; | 1418 goto done; |
| 1403 } | 1419 } |
| 1404 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1420 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 1405 << "0 bytes written with send call."; | 1421 << "0 bytes written with send call."; |
| 1406 goto error_or_close; | 1422 goto error_or_close; |
| 1407 } | 1423 } |
| 1408 done: | 1424 done: |
| 1425 UncorkSocket(); | |
| 1409 return true; | 1426 return true; |
| 1410 | 1427 |
| 1411 error_or_close: | 1428 error_or_close: |
| 1412 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1429 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 1413 << "DoWrite: error_or_close. Returning false " | 1430 << "DoWrite: error_or_close. Returning false " |
| 1414 << "after cleaning up"; | 1431 << "after cleaning up"; |
| 1415 Cleanup("DoWrite"); | 1432 Cleanup("DoWrite"); |
| 1433 UncorkSocket(); | |
| 1416 return false; | 1434 return false; |
| 1417 } | 1435 } |
| 1418 | 1436 |
| 1419 friend ostream& operator<<(ostream& os, const SMConnection& c) { | 1437 friend ostream& operator<<(ostream& os, const SMConnection& c) { |
| 1420 os << &c << "\n"; | 1438 os << &c << "\n"; |
| 1421 return os; | 1439 return os; |
| 1422 } | 1440 } |
| 1423 | 1441 |
| 1424 void Reset() { | 1442 void Reset() { |
| 1425 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Resetting"; | 1443 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Resetting"; |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1941 | 1959 |
| 1942 // SMInterface's Cleanup is currently only called by SMConnection after a | 1960 // SMInterface's Cleanup is currently only called by SMConnection after a |
| 1943 // protocol message as been fully read. Spdy's SMInterface does not need | 1961 // protocol message as been fully read. Spdy's SMInterface does not need |
| 1944 // to do any cleanup at this time. | 1962 // to do any cleanup at this time. |
| 1945 // TODO (klindsay) This method is probably not being used properly and | 1963 // TODO (klindsay) This method is probably not being used properly and |
| 1946 // some logic review and method renaming is probably in order. | 1964 // some logic review and method renaming is probably in order. |
| 1947 void Cleanup() {} | 1965 void Cleanup() {} |
| 1948 | 1966 |
| 1949 // Send a settings frame | 1967 // Send a settings frame |
| 1950 int PostAcceptHook() { | 1968 int PostAcceptHook() { |
| 1951 ssize_t bytes_written; | |
| 1952 spdy::SpdySettings settings; | 1969 spdy::SpdySettings settings; |
| 1953 spdy::SettingsFlagsAndId settings_id(0); | 1970 spdy::SettingsFlagsAndId settings_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); |
| 1954 settings_id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); | |
| 1955 settings.push_back(spdy::SpdySetting(settings_id, 100)); | 1971 settings.push_back(spdy::SpdySetting(settings_id, 100)); |
| 1956 scoped_ptr<SpdySettingsControlFrame> | 1972 SpdySettingsControlFrame* settings_frame = |
| 1957 settings_frame(spdy_framer_->CreateSettings(settings)); | 1973 spdy_framer_->CreateSettings(settings); |
| 1958 | 1974 |
| 1959 char* bytes = settings_frame->data(); | |
| 1960 size_t size = SpdyFrame::size() + settings_frame->length(); | |
| 1961 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame"; | 1975 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame"; |
| 1962 bytes_written = connection_->Send(bytes, size, | 1976 SpdyFrameDataFrame* df = new SpdyFrameDataFrame; |
| 1963 MSG_NOSIGNAL | MSG_DONTWAIT); | 1977 df->size = settings_frame->length() + SpdyFrame::size(); |
| 1964 if (static_cast<size_t>(bytes_written) != size) { | 1978 df->data = settings_frame->data(); |
| 1965 LOG(ERROR) << "Trouble sending SETTINGS frame! (" << errno << ")"; | 1979 df->frame = settings_frame; |
| 1966 if (errno == EAGAIN) { | 1980 df->delete_when_done = true; |
| 1967 return 0; | 1981 EnqueueDataFrame(df); |
| 1968 } | |
| 1969 } | |
| 1970 return 1; | 1982 return 1; |
| 1971 } | 1983 } |
| 1972 | 1984 |
| 1973 void AddAssociatedContent(FileData* file_data) { | 1985 void AddAssociatedContent(FileData* file_data) { |
| 1974 for (unsigned int i = 0; i < file_data->related_files.size(); ++i) { | 1986 for (unsigned int i = 0; i < file_data->related_files.size(); ++i) { |
| 1975 pair<int, string>& related_file = file_data->related_files[i]; | 1987 pair<int, string>& related_file = file_data->related_files[i]; |
| 1976 MemCacheIter mci; | 1988 MemCacheIter mci; |
| 1977 string filename = "GET_"; | 1989 string filename = "GET_"; |
| 1978 filename += related_file.second; | 1990 filename += related_file.second; |
| 1979 if (!memory_cache_->AssignFileData(filename, &mci)) { | 1991 if (!memory_cache_->AssignFileData(filename, &mci)) { |
| (...skipping 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3407 } | 3419 } |
| 3408 break; | 3420 break; |
| 3409 } | 3421 } |
| 3410 usleep(1000*10); // 10 ms | 3422 usleep(1000*10); // 10 ms |
| 3411 } | 3423 } |
| 3412 | 3424 |
| 3413 unlink(PIDFILE); | 3425 unlink(PIDFILE); |
| 3414 close(pidfile_fd); | 3426 close(pidfile_fd); |
| 3415 return 0; | 3427 return 0; |
| 3416 } | 3428 } |
| OLD | NEW |