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