| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "net/tools/flip_server/acceptor_thread.h" | 5 #include "net/tools/flip_server/acceptor_thread.h" | 
| 6 | 6 | 
| 7 #include <netinet/in.h> | 7 #include <netinet/in.h> | 
| 8 #include <netinet/tcp.h>  // For TCP_NODELAY | 8 #include <netinet/tcp.h>  // For TCP_NODELAY | 
| 9 #include <sys/socket.h> | 9 #include <sys/socket.h> | 
| 10 #include <sys/types.h> | 10 #include <sys/types.h> | 
| 11 | 11 | 
| 12 #include <string> | 12 #include <string> | 
| 13 | 13 | 
| 14 #include "net/tools/flip_server/constants.h" | 14 #include "net/tools/flip_server/constants.h" | 
| 15 #include "net/tools/flip_server/flip_config.h" | 15 #include "net/tools/flip_server/flip_config.h" | 
| 16 #include "net/tools/flip_server/sm_connection.h" | 16 #include "net/tools/flip_server/sm_connection.h" | 
| 17 #include "net/tools/flip_server/spdy_ssl.h" | 17 #include "net/tools/flip_server/spdy_ssl.h" | 
| 18 #include "openssl/err.h" | 18 #include "openssl/err.h" | 
| 19 #include "openssl/ssl.h" | 19 #include "openssl/ssl.h" | 
| 20 | 20 | 
| 21 namespace net { | 21 namespace net { | 
| 22 | 22 | 
| 23 SMAcceptorThread::SMAcceptorThread(FlipAcceptor *acceptor, | 23 SMAcceptorThread::SMAcceptorThread(FlipAcceptor* acceptor, | 
| 24                                    MemoryCache* memory_cache) | 24                                    MemoryCache* memory_cache) | 
| 25     : SimpleThread("SMAcceptorThread"), | 25     : SimpleThread("SMAcceptorThread"), | 
| 26       acceptor_(acceptor), | 26       acceptor_(acceptor), | 
| 27       ssl_state_(NULL), | 27       ssl_state_(NULL), | 
| 28       use_ssl_(false), | 28       use_ssl_(false), | 
| 29       idle_socket_timeout_s_(acceptor->idle_socket_timeout_s_), | 29       idle_socket_timeout_s_(acceptor->idle_socket_timeout_s_), | 
| 30       quitting_(false), | 30       quitting_(false), | 
| 31       memory_cache_(memory_cache) { | 31       memory_cache_(memory_cache) { | 
| 32   if (!acceptor->ssl_cert_filename_.empty() && | 32   if (!acceptor->ssl_cert_filename_.empty() && | 
| 33       !acceptor->ssl_key_filename_.empty()) { | 33       !acceptor->ssl_key_filename_.empty()) { | 
| 34     ssl_state_ = new SSLState; | 34     ssl_state_ = new SSLState; | 
| 35     bool use_npn = true; | 35     bool use_npn = true; | 
| 36     if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { | 36     if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { | 
| 37       use_npn = false; | 37       use_npn = false; | 
| 38     } | 38     } | 
| 39     InitSSL(ssl_state_, | 39     InitSSL(ssl_state_, | 
| 40             acceptor_->ssl_cert_filename_, | 40             acceptor_->ssl_cert_filename_, | 
| 41             acceptor_->ssl_key_filename_, | 41             acceptor_->ssl_key_filename_, | 
| 42             use_npn, | 42             use_npn, | 
| 43             acceptor_->ssl_session_expiry_, | 43             acceptor_->ssl_session_expiry_, | 
| 44             acceptor_->ssl_disable_compression_); | 44             acceptor_->ssl_disable_compression_); | 
| 45     use_ssl_ = true; | 45     use_ssl_ = true; | 
| 46   } | 46   } | 
| 47 } | 47 } | 
| 48 | 48 | 
| 49 SMAcceptorThread::~SMAcceptorThread() { | 49 SMAcceptorThread::~SMAcceptorThread() { | 
| 50   for (std::vector<SMConnection*>::iterator i = | 50   for (std::vector<SMConnection*>::iterator i = | 
| 51        allocated_server_connections_.begin(); | 51            allocated_server_connections_.begin(); | 
| 52        i != allocated_server_connections_.end(); | 52        i != allocated_server_connections_.end(); | 
| 53        ++i) { | 53        ++i) { | 
| 54     delete *i; | 54     delete *i; | 
| 55   } | 55   } | 
| 56   delete ssl_state_; | 56   delete ssl_state_; | 
| 57 } | 57 } | 
| 58 | 58 | 
| 59 SMConnection* SMAcceptorThread::NewConnection() { | 59 SMConnection* SMAcceptorThread::NewConnection() { | 
| 60   SMConnection* server = | 60   SMConnection* server = SMConnection::NewSMConnection( | 
| 61     SMConnection::NewSMConnection(&epoll_server_, ssl_state_, | 61       &epoll_server_, ssl_state_, memory_cache_, acceptor_, "client_conn: "); | 
| 62                                   memory_cache_, acceptor_, |  | 
| 63                                   "client_conn: "); |  | 
| 64   allocated_server_connections_.push_back(server); | 62   allocated_server_connections_.push_back(server); | 
| 65   VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Making new server."; | 63   VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Making new server."; | 
| 66   return server; | 64   return server; | 
| 67 } | 65 } | 
| 68 | 66 | 
| 69 SMConnection* SMAcceptorThread::FindOrMakeNewSMConnection() { | 67 SMConnection* SMAcceptorThread::FindOrMakeNewSMConnection() { | 
| 70   if (unused_server_connections_.empty()) { | 68   if (unused_server_connections_.empty()) { | 
| 71     return NewConnection(); | 69     return NewConnection(); | 
| 72   } | 70   } | 
| 73   SMConnection* server = unused_server_connections_.back(); | 71   SMConnection* server = unused_server_connections_.back(); | 
| 74   unused_server_connections_.pop_back(); | 72   unused_server_connections_.pop_back(); | 
| 75   VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Reusing server."; | 73   VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Reusing server."; | 
| 76   return server; | 74   return server; | 
| 77 } | 75 } | 
| 78 | 76 | 
| 79 void SMAcceptorThread::InitWorker() { | 77 void SMAcceptorThread::InitWorker() { | 
| 80   epoll_server_.RegisterFD(acceptor_->listen_fd_, this, EPOLLIN | EPOLLET); | 78   epoll_server_.RegisterFD(acceptor_->listen_fd_, this, EPOLLIN | EPOLLET); | 
| 81 } | 79 } | 
| 82 | 80 | 
| 83 void SMAcceptorThread::HandleConnection(int server_fd, | 81 void SMAcceptorThread::HandleConnection(int server_fd, | 
| 84                                         struct sockaddr_in *remote_addr) { | 82                                         struct sockaddr_in* remote_addr) { | 
| 85   int on = 1; | 83   int on = 1; | 
| 86   int rc; | 84   int rc; | 
| 87   if (acceptor_->disable_nagle_) { | 85   if (acceptor_->disable_nagle_) { | 
| 88     rc = setsockopt(server_fd, IPPROTO_TCP,  TCP_NODELAY, | 86     rc = setsockopt(server_fd, | 
| 89                     reinterpret_cast<char*>(&on), sizeof(on)); | 87                     IPPROTO_TCP, | 
|  | 88                     TCP_NODELAY, | 
|  | 89                     reinterpret_cast<char*>(&on), | 
|  | 90                     sizeof(on)); | 
| 90     if (rc < 0) { | 91     if (rc < 0) { | 
| 91       close(server_fd); | 92       close(server_fd); | 
| 92       LOG(ERROR) << "setsockopt() failed fd=" << server_fd; | 93       LOG(ERROR) << "setsockopt() failed fd=" << server_fd; | 
| 93       return; | 94       return; | 
| 94     } | 95     } | 
| 95   } | 96   } | 
| 96 | 97 | 
| 97   SMConnection* server_connection = FindOrMakeNewSMConnection(); | 98   SMConnection* server_connection = FindOrMakeNewSMConnection(); | 
| 98   if (server_connection == NULL) { | 99   if (server_connection == NULL) { | 
| 99     VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Closing fd " << server_fd; | 100     VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Closing fd " << server_fd; | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 121       int fd = accept(acceptor_->listen_fd_, &address, &socklen); | 122       int fd = accept(acceptor_->listen_fd_, &address, &socklen); | 
| 122       if (fd == -1) { | 123       if (fd == -1) { | 
| 123         if (errno != 11) { | 124         if (errno != 11) { | 
| 124           VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: accept fail(" | 125           VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: accept fail(" | 
| 125                   << acceptor_->listen_fd_ << "): " << errno << ": " | 126                   << acceptor_->listen_fd_ << "): " << errno << ": " | 
| 126                   << strerror(errno); | 127                   << strerror(errno); | 
| 127         } | 128         } | 
| 128         break; | 129         break; | 
| 129       } | 130       } | 
| 130       VLOG(1) << ACCEPTOR_CLIENT_IDENT << " Accepted connection"; | 131       VLOG(1) << ACCEPTOR_CLIENT_IDENT << " Accepted connection"; | 
| 131       HandleConnection(fd, (struct sockaddr_in *)&address); | 132       HandleConnection(fd, (struct sockaddr_in*)&address); | 
| 132     } | 133     } | 
| 133   } else { | 134   } else { | 
| 134     while (true) { | 135     while (true) { | 
| 135       struct sockaddr address; | 136       struct sockaddr address; | 
| 136       socklen_t socklen = sizeof(address); | 137       socklen_t socklen = sizeof(address); | 
| 137       int fd = accept(acceptor_->listen_fd_, &address, &socklen); | 138       int fd = accept(acceptor_->listen_fd_, &address, &socklen); | 
| 138       if (fd == -1) { | 139       if (fd == -1) { | 
| 139         if (errno != 11) { | 140         if (errno != 11) { | 
| 140           VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: accept fail(" | 141           VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: accept fail(" | 
| 141                   << acceptor_->listen_fd_ << "): " << errno << ": " | 142                   << acceptor_->listen_fd_ << "): " << errno << ": " | 
| 142                   << strerror(errno); | 143                   << strerror(errno); | 
| 143         } | 144         } | 
| 144         break; | 145         break; | 
| 145       } | 146       } | 
| 146       VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Accepted connection"; | 147       VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Accepted connection"; | 
| 147       HandleConnection(fd, (struct sockaddr_in *)&address); | 148       HandleConnection(fd, (struct sockaddr_in*)&address); | 
| 148     } | 149     } | 
| 149   } | 150   } | 
| 150 } | 151 } | 
| 151 | 152 | 
| 152 void SMAcceptorThread::HandleConnectionIdleTimeout() { | 153 void SMAcceptorThread::HandleConnectionIdleTimeout() { | 
| 153   static time_t oldest_time = time(NULL); | 154   static time_t oldest_time = time(NULL); | 
| 154 | 155 | 
| 155   int cur_time = time(NULL); | 156   int cur_time = time(NULL); | 
| 156   // Only iterate the list if we speculate that a connection is ready to be | 157   // Only iterate the list if we speculate that a connection is ready to be | 
| 157   // expired | 158   // expired | 
| 158   if ((cur_time - oldest_time) < idle_socket_timeout_s_) | 159   if ((cur_time - oldest_time) < idle_socket_timeout_s_) | 
| 159     return; | 160     return; | 
| 160 | 161 | 
| 161   // TODO(mbelshe): This code could be optimized, active_server_connections_ | 162   // TODO(mbelshe): This code could be optimized, active_server_connections_ | 
| 162   //                is already in-order. | 163   //                is already in-order. | 
| 163   std::list<SMConnection*>::iterator iter = active_server_connections_.begin(); | 164   std::list<SMConnection*>::iterator iter = active_server_connections_.begin(); | 
| 164   while (iter != active_server_connections_.end()) { | 165   while (iter != active_server_connections_.end()) { | 
| 165     SMConnection *conn = *iter; | 166     SMConnection* conn = *iter; | 
| 166     int elapsed_time = (cur_time - conn->last_read_time_); | 167     int elapsed_time = (cur_time - conn->last_read_time_); | 
| 167     if (elapsed_time > idle_socket_timeout_s_) { | 168     if (elapsed_time > idle_socket_timeout_s_) { | 
| 168       conn->Cleanup("Connection idle timeout reached."); | 169       conn->Cleanup("Connection idle timeout reached."); | 
| 169       iter = active_server_connections_.erase(iter); | 170       iter = active_server_connections_.erase(iter); | 
| 170       continue; | 171       continue; | 
| 171     } | 172     } | 
| 172     if (conn->last_read_time_ < oldest_time) | 173     if (conn->last_read_time_ < oldest_time) | 
| 173       oldest_time = conn->last_read_time_; | 174       oldest_time = conn->last_read_time_; | 
| 174     iter++; | 175     iter++; | 
| 175   } | 176   } | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 201     AcceptFromListenFD(); | 202     AcceptFromListenFD(); | 
| 202   } | 203   } | 
| 203 } | 204 } | 
| 204 | 205 | 
| 205 void SMAcceptorThread::SMConnectionDone(SMConnection* sc) { | 206 void SMAcceptorThread::SMConnectionDone(SMConnection* sc) { | 
| 206   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Done with connection."; | 207   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Done with connection."; | 
| 207   tmp_unused_server_connections_.push_back(sc); | 208   tmp_unused_server_connections_.push_back(sc); | 
| 208 } | 209 } | 
| 209 | 210 | 
| 210 }  // namespace net | 211 }  // namespace net | 
| 211 |  | 
| 212 |  | 
| OLD | NEW | 
|---|