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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 using spdy::SpdySynStreamControlFrame; | 144 using spdy::SpdySynStreamControlFrame; |
| 145 | 145 |
| 146 FlipConfig g_proxy_config; | 146 FlipConfig g_proxy_config; |
| 147 | 147 |
| 148 //////////////////////////////////////////////////////////////////////////////// | 148 //////////////////////////////////////////////////////////////////////////////// |
| 149 | 149 |
| 150 void PrintSslError() { | 150 void PrintSslError() { |
| 151 char buf[128]; // this buffer must be at least 120 chars long. | 151 char buf[128]; // this buffer must be at least 120 chars long. |
| 152 int error_num = ERR_get_error(); | 152 int error_num = ERR_get_error(); |
| 153 while (error_num != 0) { | 153 while (error_num != 0) { |
| 154 LOG(ERROR) << ERR_error_string(error_num, buf); | 154 ERR_error_string_n(error_num, buf, sizeof(buf)); |
| 155 LOG(ERROR) << buf; | |
| 155 error_num = ERR_get_error(); | 156 error_num = ERR_get_error(); |
| 156 } | 157 } |
| 157 } | 158 } |
| 158 | 159 |
| 159 static int ssl_set_npn_callback(SSL *s, | 160 static int ssl_set_npn_callback(SSL *s, |
| 160 const unsigned char **data, | 161 const unsigned char **data, |
| 161 unsigned int *len, | 162 unsigned int *len, |
| 162 void *arg) | 163 void *arg) |
| 163 { | 164 { |
| 164 VLOG(1) << "SSL NPN callback: advertising protocols."; | 165 VLOG(1) << "SSL NPN callback: advertising protocols."; |
| (...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1036 Cleanup("OnShutdown"); | 1037 Cleanup("OnShutdown"); |
| 1037 return; | 1038 return; |
| 1038 } | 1039 } |
| 1039 | 1040 |
| 1040 void Cleanup(const char* cleanup) { | 1041 void Cleanup(const char* cleanup) { |
| 1041 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Cleanup: " << cleanup; | 1042 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Cleanup: " << cleanup; |
| 1042 if (!initialized_) { | 1043 if (!initialized_) { |
| 1043 return; | 1044 return; |
| 1044 } | 1045 } |
| 1045 Reset(); | 1046 Reset(); |
| 1046 if (connection_pool_) { | 1047 if (connection_pool_) |
| 1047 connection_pool_->SMConnectionDone(this); | 1048 connection_pool_->SMConnectionDone(this); |
| 1048 } | 1049 if (sm_interface_) |
| 1049 if (sm_interface_) { | |
| 1050 sm_interface_->ResetForNewConnection(); | 1050 sm_interface_->ResetForNewConnection(); |
| 1051 } | |
| 1052 last_read_time_ = 0; | 1051 last_read_time_ = 0; |
| 1053 } | 1052 } |
| 1054 | 1053 |
| 1055 private: | 1054 private: |
| 1056 void HandleEvents() { | 1055 void HandleEvents() { |
| 1057 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Received: " | 1056 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Received: " |
| 1058 << EpollServer::EventMaskToString(events_).c_str(); | 1057 << EpollServer::EventMaskToString(events_).c_str(); |
| 1059 | 1058 |
| 1060 if (events_ & EPOLLIN) { | 1059 if (events_ & EPOLLIN) { |
| 1061 if (!DoRead()) | 1060 if (!DoRead()) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1094 if (events_ & (EPOLLHUP | EPOLLERR)) { | 1093 if (events_ & (EPOLLHUP | EPOLLERR)) { |
| 1095 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "!!! Got HUP or ERR"; | 1094 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "!!! Got HUP or ERR"; |
| 1096 goto handle_close_or_error; | 1095 goto handle_close_or_error; |
| 1097 } | 1096 } |
| 1098 return; | 1097 return; |
| 1099 | 1098 |
| 1100 handle_close_or_error: | 1099 handle_close_or_error: |
| 1101 Cleanup("HandleEvents"); | 1100 Cleanup("HandleEvents"); |
| 1102 } | 1101 } |
| 1103 | 1102 |
| 1103 // Decide if SPDY was negotiated. | |
| 1104 bool WasSpdyNegotiated() { | |
| 1105 if (FLAGS_force_spdy) | |
| 1106 return true; | |
| 1107 | |
| 1108 // If this is an SSL connection, check if NPN specifies SPDY. | |
| 1109 if (ssl_) { | |
| 1110 const unsigned char *npn_proto; | |
| 1111 unsigned int npn_proto_len; | |
| 1112 SSL_get0_next_proto_negotiated(ssl_, &npn_proto, &npn_proto_len); | |
| 1113 if (npn_proto_len > 0) { | |
| 1114 string npn_proto_str((const char *)npn_proto, npn_proto_len); | |
| 1115 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1116 << "NPN protocol detected: " << npn_proto_str; | |
| 1117 if (!strncmp(reinterpret_cast<const char*>(npn_proto), | |
| 1118 "spdy/2", npn_proto_len)) | |
| 1119 return true; | |
| 1120 } | |
| 1121 } | |
| 1122 | |
| 1123 return false; | |
| 1124 } | |
| 1125 | |
| 1126 // Initialize the protocol interfaces we'll need for this connection. | |
| 1127 // Returns true if successful, false otherwise. | |
| 1128 bool SetupProtocolInterfaces() { | |
| 1129 DCHECK(!protocol_detected_); | |
| 1130 protocol_detected_ = true; | |
| 1131 | |
| 1132 bool spdy_negotiated = WasSpdyNegotiated(); | |
| 1133 bool using_ssl = ssl_ != NULL; | |
| 1134 | |
| 1135 if (using_ssl) | |
| 1136 VLOG(1) << (SSL_session_reused(ssl_) ? "Resumed" : "Renegotiated") | |
| 1137 << " SSL Session."; | |
| 1138 | |
| 1139 if (acceptor_->spdy_only_ && !spdy_negotiated) { | |
| 1140 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1141 << "SPDY proxy only, closing HTTPS connection."; | |
| 1142 return false; | |
| 1143 } | |
| 1144 | |
| 1145 switch (acceptor_->flip_handler_type_) { | |
| 1146 case FLIP_HANDLER_HTTP_SERVER: | |
| 1147 { | |
| 1148 DCHECK(!spdy_negotiated); | |
| 1149 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1150 << (sm_http_interface_ ? "Creating" : "Reusing") | |
| 1151 << " HTTP interface."; | |
| 1152 if (!sm_http_interface_) | |
| 1153 sm_http_interface_ = NewHttpSM(this, NULL, epoll_server_, | |
| 1154 memory_cache_, acceptor_); | |
| 1155 sm_interface_ = sm_http_interface_; | |
| 1156 } | |
| 1157 break; | |
| 1158 case FLIP_HANDLER_PROXY: | |
| 1159 { | |
| 1160 DCHECK(spdy_negotiated); // This is only a SPDY->SPDY proxy. | |
|
kelindsay
2011/01/25 19:00:28
FLIP_HANDLER_PROXY indicates that we can accept bo
| |
| 1161 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1162 << (sm_streamer_interface_ ? "Creating" : "Reusing") | |
| 1163 << " PROXY Streamer interface."; | |
| 1164 if (!sm_streamer_interface_) | |
| 1165 sm_streamer_interface_ = NewStreamerSM(this, NULL, | |
| 1166 epoll_server_, | |
| 1167 acceptor_); | |
| 1168 sm_interface_ = sm_streamer_interface_; | |
| 1169 } | |
| 1170 // Falls through into the case below. | |
| 1171 case FLIP_HANDLER_SPDY_SERVER: | |
| 1172 { | |
| 1173 DCHECK(spdy_negotiated); | |
| 1174 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1175 << (sm_spdy_interface_ ? "Creating" : "Reusing") | |
| 1176 << " SPDY interface."; | |
| 1177 if (!sm_spdy_interface_) | |
| 1178 sm_spdy_interface_ = NewSpdySM(this, NULL, epoll_server_, | |
| 1179 memory_cache_, acceptor_); | |
| 1180 sm_interface_ = sm_spdy_interface_; | |
| 1181 } | |
| 1182 break; | |
| 1183 } | |
| 1184 if (!sm_interface_->PostAcceptHook()) | |
| 1185 return false; | |
| 1186 | |
| 1187 return true; | |
| 1188 } | |
| 1189 | |
| 1104 bool DoRead() { | 1190 bool DoRead() { |
| 1105 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead()"; | 1191 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead()"; |
| 1106 while (!read_buffer_.Full()) { | 1192 while (!read_buffer_.Full()) { |
| 1107 char* bytes; | 1193 char* bytes; |
| 1108 int size; | 1194 int size; |
| 1109 if (fd_ == -1) { | 1195 if (fd_ == -1) { |
| 1110 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1196 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 1111 << "DoRead(): fd_ == -1. Invalid FD. Returning false"; | 1197 << "DoRead(): fd_ == -1. Invalid FD. Returning false"; |
| 1112 return false; | 1198 return false; |
| 1113 } | 1199 } |
| 1114 read_buffer_.GetWritablePtr(&bytes, &size); | 1200 read_buffer_.GetWritablePtr(&bytes, &size); |
| 1115 ssize_t bytes_read = 0; | 1201 ssize_t bytes_read = 0; |
| 1116 if (ssl_) { | 1202 if (ssl_) { |
| 1117 bytes_read = SSL_read(ssl_, bytes, size); | 1203 bytes_read = SSL_read(ssl_, bytes, size); |
| 1118 if (bytes_read < 0) { | 1204 if (bytes_read < 0) { |
| 1119 switch(SSL_get_error(ssl_, bytes_read)) { | 1205 int err = SSL_get_error(ssl_, bytes_read); |
| 1206 switch(err) { | |
| 1120 case SSL_ERROR_WANT_READ: | 1207 case SSL_ERROR_WANT_READ: |
| 1121 case SSL_ERROR_WANT_WRITE: | 1208 case SSL_ERROR_WANT_WRITE: |
| 1122 case SSL_ERROR_WANT_ACCEPT: | 1209 case SSL_ERROR_WANT_ACCEPT: |
| 1123 case SSL_ERROR_WANT_CONNECT: | 1210 case SSL_ERROR_WANT_CONNECT: |
| 1124 events_ &= ~EPOLLIN; | 1211 events_ &= ~EPOLLIN; |
| 1212 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1213 << "DoRead: SSL WANT_XXX: " << err; | |
| 1125 goto done; | 1214 goto done; |
| 1126 default: | 1215 default: |
| 1127 PrintSslError(); | 1216 PrintSslError(); |
| 1128 goto error_or_close; | 1217 goto error_or_close; |
| 1129 } | 1218 } |
| 1130 } | 1219 } |
| 1131 } else { | 1220 } else { |
| 1132 bytes_read = recv(fd_, bytes, size, MSG_DONTWAIT); | 1221 bytes_read = recv(fd_, bytes, size, MSG_DONTWAIT); |
| 1133 } | 1222 } |
| 1134 int stored_errno = errno; | 1223 int stored_errno = errno; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1146 default: | 1235 default: |
| 1147 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1236 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 1148 << "While calling recv, got error: " | 1237 << "While calling recv, got error: " |
| 1149 << (ssl_?"(ssl error)":strerror(stored_errno)); | 1238 << (ssl_?"(ssl error)":strerror(stored_errno)); |
| 1150 goto error_or_close; | 1239 goto error_or_close; |
| 1151 } | 1240 } |
| 1152 } else if (bytes_read > 0) { | 1241 } else if (bytes_read > 0) { |
| 1153 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "read " << bytes_read | 1242 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "read " << bytes_read |
| 1154 << " bytes"; | 1243 << " bytes"; |
| 1155 last_read_time_ = time(NULL); | 1244 last_read_time_ = time(NULL); |
| 1245 // If the protocol hasn't been detected yet, set up the handlers | |
| 1246 // we'll need. | |
| 1156 if (!protocol_detected_) { | 1247 if (!protocol_detected_) { |
| 1157 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { | 1248 if (!SetupProtocolInterfaces()) { |
| 1158 // Http Server | 1249 LOG(ERROR) << "Error setting up protocol interfaces."; |
| 1159 protocol_detected_ = true; | |
| 1160 if (!sm_http_interface_) { | |
| 1161 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1162 << "Created HTTP interface."; | |
| 1163 sm_http_interface_ = NewHttpSM(this, NULL, epoll_server_, | |
| 1164 memory_cache_, acceptor_); | |
| 1165 } else { | |
| 1166 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1167 << "Reusing HTTP interface."; | |
| 1168 } | |
| 1169 sm_interface_ = sm_http_interface_; | |
| 1170 } else if (ssl_) { | |
| 1171 protocol_detected_ = true; | |
| 1172 if (SSL_session_reused(ssl_) == 0) { | |
| 1173 VLOG(1) << "Session status: renegotiated"; | |
| 1174 } else { | |
| 1175 VLOG(1) << "Session status: resumed"; | |
| 1176 } | |
| 1177 bool spdy_negotiated = FLAGS_force_spdy; | |
| 1178 if (!spdy_negotiated) { | |
| 1179 const unsigned char *npn_proto; | |
| 1180 unsigned int npn_proto_len; | |
| 1181 SSL_get0_next_proto_negotiated(ssl_, &npn_proto, &npn_proto_len); | |
| 1182 if (npn_proto_len > 0) { | |
| 1183 string npn_proto_str((const char *)npn_proto, npn_proto_len); | |
| 1184 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1185 << "NPN protocol detected: " << npn_proto_str; | |
| 1186 } else { | |
| 1187 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1188 << "NPN protocol detected: none"; | |
| 1189 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_SPDY_SERVER) { | |
| 1190 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1191 << "NPN protocol: Could not negotiate SPDY protocol."; | |
| 1192 goto error_or_close; | |
| 1193 } | |
| 1194 } | |
| 1195 if (npn_proto_len > 0 && | |
| 1196 !strncmp(reinterpret_cast<const char*>(npn_proto), | |
| 1197 "spdy/2", npn_proto_len)) { | |
| 1198 spdy_negotiated = true; | |
| 1199 } | |
| 1200 } | |
| 1201 if (spdy_negotiated) { | |
| 1202 if (!sm_spdy_interface_) { | |
| 1203 sm_spdy_interface_ = NewSpdySM(this, NULL, epoll_server_, | |
| 1204 memory_cache_, acceptor_); | |
| 1205 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1206 << "Created SPDY interface."; | |
| 1207 } else { | |
| 1208 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1209 << "Reusing SPDY interface."; | |
| 1210 } | |
| 1211 sm_interface_ = sm_spdy_interface_; | |
| 1212 } else if (acceptor_->spdy_only_) { | |
| 1213 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1214 << "SPDY proxy only, closing HTTPS connection."; | |
| 1215 goto error_or_close; | |
| 1216 } else { | |
| 1217 if (!sm_streamer_interface_) { | |
| 1218 sm_streamer_interface_ = NewStreamerSM(this, NULL, | |
| 1219 epoll_server_, | |
| 1220 acceptor_); | |
| 1221 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1222 << "Created Streamer interface."; | |
| 1223 } else { | |
| 1224 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 1225 << "Reusing Streamer interface: "; | |
| 1226 } | |
| 1227 sm_interface_ = sm_streamer_interface_; | |
| 1228 } | |
| 1229 } | |
| 1230 if (sm_interface_->PostAcceptHook() == 0) { | |
| 1231 goto error_or_close; | 1250 goto error_or_close; |
| 1232 } | 1251 } |
| 1233 } | 1252 } |
| 1234 read_buffer_.AdvanceWritablePtr(bytes_read); | 1253 read_buffer_.AdvanceWritablePtr(bytes_read); |
| 1235 if (!DoConsumeReadData()) { | 1254 if (!DoConsumeReadData()) |
| 1236 goto error_or_close; | 1255 goto error_or_close; |
| 1237 } | |
| 1238 continue; | 1256 continue; |
| 1239 } else { // bytes_read == 0 | 1257 } else { // bytes_read == 0 |
| 1240 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1258 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 1241 << "0 bytes read with recv call."; | 1259 << "0 bytes read with recv call."; |
| 1242 } | 1260 } |
| 1243 goto error_or_close; | 1261 goto error_or_close; |
| 1244 } | 1262 } |
| 1245 done: | 1263 done: |
| 1264 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead done!"; | |
| 1246 return true; | 1265 return true; |
| 1247 | 1266 |
| 1248 error_or_close: | 1267 error_or_close: |
| 1249 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1268 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 1250 << "DoRead(): error_or_close. " | 1269 << "DoRead(): error_or_close. " |
| 1251 << "Cleaning up, then returning false"; | 1270 << "Cleaning up, then returning false"; |
| 1252 Cleanup("DoRead"); | 1271 Cleanup("DoRead"); |
| 1253 return false; | 1272 return false; |
| 1254 } | 1273 } |
| 1255 | 1274 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1310 } | 1329 } |
| 1311 if (output_list_.empty()) { | 1330 if (output_list_.empty()) { |
| 1312 events_ &= ~EPOLLOUT; | 1331 events_ &= ~EPOLLOUT; |
| 1313 } | 1332 } |
| 1314 } | 1333 } |
| 1315 while (!output_list_.empty()) { | 1334 while (!output_list_.empty()) { |
| 1316 VLOG(2) << log_prefix_ << "DoWrite: Items in output list: " | 1335 VLOG(2) << log_prefix_ << "DoWrite: Items in output list: " |
| 1317 << output_list_.size(); | 1336 << output_list_.size(); |
| 1318 if (bytes_sent >= max_bytes_sent_per_dowrite_) { | 1337 if (bytes_sent >= max_bytes_sent_per_dowrite_) { |
| 1319 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1338 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 1320 << " byte sent >= max bytes sent per write: Setting EPOLLOUT"; | 1339 << " byte sent >= max bytes sent per write: Setting EPOLLOUT: " |
| 1340 << bytes_sent; | |
| 1321 events_ |= EPOLLOUT; | 1341 events_ |= EPOLLOUT; |
| 1322 break; | 1342 break; |
| 1323 } | 1343 } |
| 1324 if (sm_interface_ && output_list_.size() < 2) { | 1344 if (sm_interface_ && output_list_.size() < 2) { |
| 1325 sm_interface_->GetOutput(); | 1345 sm_interface_->GetOutput(); |
| 1326 } | 1346 } |
| 1327 DataFrame* data_frame = output_list_.front(); | 1347 DataFrame* data_frame = output_list_.front(); |
| 1328 const char* bytes = data_frame->data; | 1348 const char* bytes = data_frame->data; |
| 1329 int size = data_frame->size; | 1349 int size = data_frame->size; |
| 1330 bytes += data_frame->index; | 1350 bytes += data_frame->index; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1421 protocol_detected_ = false; | 1441 protocol_detected_ = false; |
| 1422 events_ = 0; | 1442 events_ = 0; |
| 1423 for (list<DataFrame*>::iterator i = | 1443 for (list<DataFrame*>::iterator i = |
| 1424 output_list_.begin(); | 1444 output_list_.begin(); |
| 1425 i != output_list_.end(); | 1445 i != output_list_.end(); |
| 1426 ++i) { | 1446 ++i) { |
| 1427 delete *i; | 1447 delete *i; |
| 1428 } | 1448 } |
| 1429 output_list_.clear(); | 1449 output_list_.clear(); |
| 1430 } | 1450 } |
| 1431 | |
| 1432 }; | 1451 }; |
| 1433 | 1452 |
| 1434 //////////////////////////////////////////////////////////////////////////////// | 1453 //////////////////////////////////////////////////////////////////////////////// |
| 1435 | 1454 |
| 1436 class OutputOrdering { | 1455 class OutputOrdering { |
| 1437 public: | 1456 public: |
| 1438 typedef list<MemCacheIter> PriorityRing; | 1457 typedef list<MemCacheIter> PriorityRing; |
| 1439 | 1458 |
| 1440 typedef map<uint32, PriorityRing> PriorityMap; | 1459 typedef map<uint32, PriorityRing> PriorityMap; |
| 1441 | 1460 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1617 } | 1636 } |
| 1618 }; | 1637 }; |
| 1619 | 1638 |
| 1620 | 1639 |
| 1621 //////////////////////////////////////////////////////////////////////////////// | 1640 //////////////////////////////////////////////////////////////////////////////// |
| 1622 | 1641 |
| 1623 class SpdySM : public SpdyFramerVisitorInterface, public SMInterface { | 1642 class SpdySM : public SpdyFramerVisitorInterface, public SMInterface { |
| 1624 private: | 1643 private: |
| 1625 uint64 seq_num_; | 1644 uint64 seq_num_; |
| 1626 SpdyFramer* spdy_framer_; | 1645 SpdyFramer* spdy_framer_; |
| 1646 bool valid_spdy_session_; // True if we have seen valid data on this session. | |
| 1647 // Use this to fail fast when junk is sent to our | |
| 1648 // port. | |
| 1627 | 1649 |
| 1628 SMConnection* connection_; | 1650 SMConnection* connection_; |
| 1629 OutputList* client_output_list_; | 1651 OutputList* client_output_list_; |
| 1630 OutputOrdering client_output_ordering_; | 1652 OutputOrdering client_output_ordering_; |
| 1631 uint32 next_outgoing_stream_id_; | 1653 uint32 next_outgoing_stream_id_; |
| 1632 EpollServer* epoll_server_; | 1654 EpollServer* epoll_server_; |
| 1633 FlipAcceptor* acceptor_; | 1655 FlipAcceptor* acceptor_; |
| 1634 MemoryCache* memory_cache_; | 1656 MemoryCache* memory_cache_; |
| 1635 vector<SMInterface*> server_interface_list; | 1657 vector<SMInterface*> server_interface_list; |
| 1636 vector<int32> unused_server_interface_list; | 1658 vector<int32> unused_server_interface_list; |
| 1637 typedef map<uint32,SMInterface*> StreamToSmif; | 1659 typedef map<uint32,SMInterface*> StreamToSmif; |
| 1638 StreamToSmif stream_to_smif_; | 1660 StreamToSmif stream_to_smif_; |
| 1639 public: | 1661 public: |
| 1640 SpdySM(SMConnection* connection, | 1662 SpdySM(SMConnection* connection, |
| 1641 SMInterface* sm_http_interface, | 1663 SMInterface* sm_http_interface, |
| 1642 EpollServer* epoll_server, | 1664 EpollServer* epoll_server, |
| 1643 MemoryCache* memory_cache, | 1665 MemoryCache* memory_cache, |
| 1644 FlipAcceptor* acceptor) | 1666 FlipAcceptor* acceptor) |
| 1645 : seq_num_(0), | 1667 : seq_num_(0), |
| 1646 spdy_framer_(new SpdyFramer), | 1668 spdy_framer_(new SpdyFramer), |
| 1669 valid_spdy_session_(false), | |
| 1647 connection_(connection), | 1670 connection_(connection), |
| 1648 client_output_list_(connection->output_list()), | 1671 client_output_list_(connection->output_list()), |
| 1649 client_output_ordering_(connection), | 1672 client_output_ordering_(connection), |
| 1650 next_outgoing_stream_id_(2), | 1673 next_outgoing_stream_id_(2), |
| 1651 epoll_server_(epoll_server), | 1674 epoll_server_(epoll_server), |
| 1652 acceptor_(acceptor), | 1675 acceptor_(acceptor), |
| 1653 memory_cache_(memory_cache) { | 1676 memory_cache_(memory_cache) { |
| 1654 spdy_framer_->set_visitor(this); | 1677 spdy_framer_->set_visitor(this); |
| 1655 } | 1678 } |
| 1656 | 1679 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1802 const SpdySynStreamControlFrame* syn_stream = | 1825 const SpdySynStreamControlFrame* syn_stream = |
| 1803 reinterpret_cast<const SpdySynStreamControlFrame*>(frame); | 1826 reinterpret_cast<const SpdySynStreamControlFrame*>(frame); |
| 1804 | 1827 |
| 1805 string http_data; | 1828 string http_data; |
| 1806 bool is_https_scheme; | 1829 bool is_https_scheme; |
| 1807 int ret = SpdyHandleNewStream(frame, http_data, &is_https_scheme); | 1830 int ret = SpdyHandleNewStream(frame, http_data, &is_https_scheme); |
| 1808 if (!ret) { | 1831 if (!ret) { |
| 1809 LOG(ERROR) << "SpdySM: Could not convert spdy into http."; | 1832 LOG(ERROR) << "SpdySM: Could not convert spdy into http."; |
| 1810 break; | 1833 break; |
| 1811 } | 1834 } |
| 1835 // We've seen a valid looking SYN_STREAM, consider this to have | |
| 1836 // been a real spdy session. | |
| 1837 valid_spdy_session_ = true; | |
| 1812 | 1838 |
| 1813 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { | 1839 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { |
| 1814 string server_ip; | 1840 string server_ip; |
| 1815 string server_port; | 1841 string server_port; |
| 1816 if (is_https_scheme) { | 1842 if (is_https_scheme) { |
| 1817 server_ip = acceptor_->https_server_ip_; | 1843 server_ip = acceptor_->https_server_ip_; |
| 1818 server_port = acceptor_->https_server_port_; | 1844 server_port = acceptor_->https_server_port_; |
| 1819 } else { | 1845 } else { |
| 1820 server_ip = acceptor_->http_server_ip_; | 1846 server_ip = acceptor_->http_server_ip_; |
| 1821 server_port = acceptor_->http_server_port_; | 1847 server_port = acceptor_->http_server_port_; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1847 break; | 1873 break; |
| 1848 | 1874 |
| 1849 default: | 1875 default: |
| 1850 LOG(ERROR) << "SpdySM: Unknown control frame type"; | 1876 LOG(ERROR) << "SpdySM: Unknown control frame type"; |
| 1851 } | 1877 } |
| 1852 } | 1878 } |
| 1853 virtual void OnStreamFrameData(SpdyStreamId stream_id, | 1879 virtual void OnStreamFrameData(SpdyStreamId stream_id, |
| 1854 const char* data, size_t len) { | 1880 const char* data, size_t len) { |
| 1855 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: StreamData(" << stream_id | 1881 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: StreamData(" << stream_id |
| 1856 << ", [" << len << "])"; | 1882 << ", [" << len << "])"; |
| 1857 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { | 1883 StreamToSmif::iterator it = stream_to_smif_.find(stream_id); |
| 1858 stream_to_smif_[stream_id]->ProcessWriteInput(data, len); | 1884 if (it == stream_to_smif_.end()) { |
| 1885 VLOG(2) << "Dropping frame from unknown stream " << stream_id; | |
| 1886 if (!valid_spdy_session_) | |
| 1887 connection_->Cleanup("invalid"); | |
| 1888 return; | |
| 1859 } | 1889 } |
| 1890 | |
| 1891 SMInterface* interface = it->second; | |
| 1892 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) | |
| 1893 interface->ProcessWriteInput(data, len); | |
| 1860 } | 1894 } |
| 1861 | 1895 |
| 1862 public: | 1896 public: |
| 1863 size_t ProcessReadInput(const char* data, size_t len) { | 1897 size_t ProcessReadInput(const char* data, size_t len) { |
| 1864 return spdy_framer_->ProcessInput(data, len); | 1898 return spdy_framer_->ProcessInput(data, len); |
| 1865 } | 1899 } |
| 1866 | 1900 |
| 1867 size_t ProcessWriteInput(const char* data, size_t len) { | 1901 size_t ProcessWriteInput(const char* data, size_t len) { |
| 1868 return 0; | 1902 return 0; |
| 1869 } | 1903 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1890 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reset for new interface: " | 1924 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reset for new interface: " |
| 1891 << "server_idx: " << server_idx; | 1925 << "server_idx: " << server_idx; |
| 1892 unused_server_interface_list.push_back(server_idx); | 1926 unused_server_interface_list.push_back(server_idx); |
| 1893 } | 1927 } |
| 1894 | 1928 |
| 1895 void ResetForNewConnection() { | 1929 void ResetForNewConnection() { |
| 1896 // seq_num is not cleared, intentionally. | 1930 // seq_num is not cleared, intentionally. |
| 1897 delete spdy_framer_; | 1931 delete spdy_framer_; |
| 1898 spdy_framer_ = new SpdyFramer; | 1932 spdy_framer_ = new SpdyFramer; |
| 1899 spdy_framer_->set_visitor(this); | 1933 spdy_framer_->set_visitor(this); |
| 1934 valid_spdy_session_ = false; | |
| 1900 client_output_ordering_.Reset(); | 1935 client_output_ordering_.Reset(); |
| 1901 next_outgoing_stream_id_ = 2; | 1936 next_outgoing_stream_id_ = 2; |
| 1902 } | 1937 } |
| 1903 | 1938 |
| 1904 // SMInterface's Cleanup is currently only called by SMConnection after a | 1939 // SMInterface's Cleanup is currently only called by SMConnection after a |
| 1905 // protocol message as been fully read. Spdy's SMInterface does not need | 1940 // protocol message as been fully read. Spdy's SMInterface does not need |
| 1906 // to do any cleanup at this time. | 1941 // to do any cleanup at this time. |
| 1907 // TODO (klindsay) This method is probably not being used properly and | 1942 // TODO (klindsay) This method is probably not being used properly and |
| 1908 // some logic review and method renaming is probably in order. | 1943 // some logic review and method renaming is probably in order. |
| 1909 void Cleanup() {} | 1944 void Cleanup() {} |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2415 seq_num_ = 0; | 2450 seq_num_ = 0; |
| 2416 output_ordering_.Reset(); | 2451 output_ordering_.Reset(); |
| 2417 http_framer_->Reset(); | 2452 http_framer_->Reset(); |
| 2418 if (sm_spdy_interface_) { | 2453 if (sm_spdy_interface_) { |
| 2419 sm_spdy_interface_->ResetForNewInterface(server_idx_); | 2454 sm_spdy_interface_->ResetForNewInterface(server_idx_); |
| 2420 } | 2455 } |
| 2421 } | 2456 } |
| 2422 | 2457 |
| 2423 void Cleanup() { | 2458 void Cleanup() { |
| 2424 if (!(acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER)) { | 2459 if (!(acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER)) { |
| 2425 connection_->Cleanup("HttpSM Request Fully Read: stream_id " + | 2460 VLOG(2) << "HttpSM Request Fully Read; stream_id: " << stream_id_; |
| 2426 stream_id_); | 2461 connection_->Cleanup("request complete"); |
| 2427 } | 2462 } |
| 2428 } | 2463 } |
| 2429 | 2464 |
| 2430 int PostAcceptHook() { | 2465 int PostAcceptHook() { |
| 2431 return 1; | 2466 return 1; |
| 2432 } | 2467 } |
| 2433 | 2468 |
| 2434 void NewStream(uint32 stream_id, uint32 priority, const string& filename) { | 2469 void NewStream(uint32 stream_id, uint32 priority, const string& filename) { |
| 2435 MemCacheIter mci; | 2470 MemCacheIter mci; |
| 2436 mci.stream_id = stream_id; | 2471 mci.stream_id = stream_id; |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2813 SMAcceptorThread(FlipAcceptor *acceptor, | 2848 SMAcceptorThread(FlipAcceptor *acceptor, |
| 2814 MemoryCache* memory_cache) : | 2849 MemoryCache* memory_cache) : |
| 2815 SimpleThread("SMAcceptorThread"), | 2850 SimpleThread("SMAcceptorThread"), |
| 2816 acceptor_(acceptor), | 2851 acceptor_(acceptor), |
| 2817 ssl_state_(NULL), | 2852 ssl_state_(NULL), |
| 2818 use_ssl_(false), | 2853 use_ssl_(false), |
| 2819 quitting_(false), | 2854 quitting_(false), |
| 2820 memory_cache_(memory_cache) | 2855 memory_cache_(memory_cache) |
| 2821 { | 2856 { |
| 2822 if (!acceptor->ssl_cert_filename_.empty() && | 2857 if (!acceptor->ssl_cert_filename_.empty() && |
| 2823 !acceptor->ssl_cert_filename_.empty()) { | 2858 !acceptor->ssl_key_filename_.empty()) { |
| 2824 ssl_state_ = new SSLState; | 2859 ssl_state_ = new SSLState; |
| 2825 bool use_npn = true; | 2860 bool use_npn = true; |
| 2826 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { | 2861 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { |
| 2827 use_npn = false; | 2862 use_npn = false; |
| 2828 } | 2863 } |
| 2829 spdy_init_ssl(ssl_state_, acceptor_->ssl_cert_filename_, | 2864 spdy_init_ssl(ssl_state_, acceptor_->ssl_cert_filename_, |
| 2830 acceptor_->ssl_key_filename_, use_npn); | 2865 acceptor_->ssl_key_filename_, use_npn); |
| 2831 use_ssl_ = true; | 2866 use_ssl_ = true; |
| 2832 } | 2867 } |
| 2833 } | 2868 } |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3369 } | 3404 } |
| 3370 break; | 3405 break; |
| 3371 } | 3406 } |
| 3372 usleep(1000*10); // 10 ms | 3407 usleep(1000*10); // 10 ms |
| 3373 } | 3408 } |
| 3374 | 3409 |
| 3375 unlink(PIDFILE); | 3410 unlink(PIDFILE); |
| 3376 close(pidfile_fd); | 3411 close(pidfile_fd); |
| 3377 return 0; | 3412 return 0; |
| 3378 } | 3413 } |
| OLD | NEW |