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 |