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> |
| 10 #include <sys/stat.h> |
9 #include <unistd.h> | 11 #include <unistd.h> |
10 #include <openssl/err.h> | 12 #include <openssl/err.h> |
11 #include <openssl/ssl.h> | 13 #include <openssl/ssl.h> |
12 #include <signal.h> | 14 #include <signal.h> |
13 | 15 |
14 #include <deque> | 16 #include <deque> |
15 #include <iostream> | 17 #include <iostream> |
16 #include <limits> | 18 #include <limits> |
17 #include <vector> | 19 #include <vector> |
18 #include <list> | 20 #include <list> |
(...skipping 22 matching lines...) Expand all Loading... |
41 //////////////////////////////////////////////////////////////////////////////// | 43 //////////////////////////////////////////////////////////////////////////////// |
42 | 44 |
43 using std::deque; | 45 using std::deque; |
44 using std::list; | 46 using std::list; |
45 using std::map; | 47 using std::map; |
46 using std::ostream; | 48 using std::ostream; |
47 using std::pair; | 49 using std::pair; |
48 using std::string; | 50 using std::string; |
49 using std::vector; | 51 using std::vector; |
50 using std::cout; | 52 using std::cout; |
| 53 using std::cerr; |
51 | 54 |
52 //////////////////////////////////////////////////////////////////////////////// | 55 //////////////////////////////////////////////////////////////////////////////// |
53 | 56 |
54 #define IPV4_PRINTABLE_FORMAT(IP) (((IP)>>0)&0xff),(((IP)>>8)&0xff), \ | 57 #define IPV4_PRINTABLE_FORMAT(IP) (((IP)>>0)&0xff),(((IP)>>8)&0xff), \ |
55 (((IP)>>16)&0xff),(((IP)>>24)&0xff) | 58 (((IP)>>16)&0xff),(((IP)>>24)&0xff) |
56 | 59 |
57 #define ACCEPTOR_CLIENT_IDENT acceptor_->listen_ip_ << ":" \ | 60 #define ACCEPTOR_CLIENT_IDENT acceptor_->listen_ip_ << ":" \ |
58 << acceptor_->listen_port_ << " " | 61 << acceptor_->listen_port_ << " " |
59 | 62 |
60 #define NEXT_PROTO_STRING "\x06spdy/2\x08http/1.1\x08http/1.0" | 63 #define NEXT_PROTO_STRING "\x06spdy/2\x08http/1.1\x08http/1.0" |
61 | 64 |
62 #define SSL_CTX_DEFAULT_CIPHER_LIST "!aNULL:!ADH:!eNull:!LOW:!EXP:RC4+RSA:MEDIUM
:HIGH" | 65 #define SSL_CTX_DEFAULT_CIPHER_LIST "!aNULL:!ADH:!eNull:!LOW:!EXP:RC4+RSA:MEDIUM
:HIGH" |
63 | 66 |
| 67 #define PIDFILE "/var/run/flip-server.pid" |
| 68 |
64 // If true, then disables the nagle algorithm); | 69 // If true, then disables the nagle algorithm); |
65 bool FLAGS_disable_nagle = true; | 70 bool FLAGS_disable_nagle = true; |
66 | 71 |
67 // The number of times that accept() will be called when the | 72 // The number of times that accept() will be called when the |
68 // alarm goes off when the accept_using_alarm flag is set to true. | 73 // alarm goes off when the accept_using_alarm flag is set to true. |
69 // If set to 0, accept() will be performed until the accept queue | 74 // If set to 0, accept() will be performed until the accept queue |
70 // is completely drained and the accept() call returns an error); | 75 // is completely drained and the accept() call returns an error); |
71 int32 FLAGS_accepts_per_wake = 0; | 76 int32 FLAGS_accepts_per_wake = 0; |
72 | 77 |
73 // The size of the TCP accept backlog); | 78 // The size of the TCP accept backlog); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 | 287 |
283 //////////////////////////////////////////////////////////////////////////////// | 288 //////////////////////////////////////////////////////////////////////////////// |
284 | 289 |
285 class DataFrame { | 290 class DataFrame { |
286 public: | 291 public: |
287 const char* data; | 292 const char* data; |
288 size_t size; | 293 size_t size; |
289 bool delete_when_done; | 294 bool delete_when_done; |
290 size_t index; | 295 size_t index; |
291 DataFrame() : data(NULL), size(0), delete_when_done(false), index(0) {} | 296 DataFrame() : data(NULL), size(0), delete_when_done(false), index(0) {} |
292 void MaybeDelete() { | 297 virtual void MaybeDelete() { |
293 if (delete_when_done) { | 298 if (delete_when_done) { |
294 delete[] data; | 299 delete[] data; |
295 } | 300 } |
296 } | 301 } |
| 302 virtual ~DataFrame() { |
| 303 MaybeDelete(); |
| 304 } |
| 305 }; |
| 306 |
| 307 class SpdyFrameDataFrame : public DataFrame { |
| 308 public: |
| 309 SpdyFrame* frame; |
| 310 virtual void MaybeDelete() { |
| 311 if (delete_when_done) { |
| 312 delete frame; |
| 313 } |
| 314 } |
297 }; | 315 }; |
298 | 316 |
299 //////////////////////////////////////////////////////////////////////////////// | 317 //////////////////////////////////////////////////////////////////////////////// |
300 | 318 |
301 class StoreBodyAndHeadersVisitor: public BalsaVisitorInterface { | 319 class StoreBodyAndHeadersVisitor: public BalsaVisitorInterface { |
302 public: | 320 public: |
303 BalsaHeaders headers; | 321 BalsaHeaders headers; |
304 string body; | 322 string body; |
305 bool error_; | 323 bool error_; |
306 | 324 |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 class SMInterface { | 709 class SMInterface { |
692 public: | 710 public: |
693 virtual void InitSMInterface(SMInterface* sm_other_interface, | 711 virtual void InitSMInterface(SMInterface* sm_other_interface, |
694 int32 server_idx) = 0; | 712 int32 server_idx) = 0; |
695 virtual void InitSMConnection(SMConnectionPoolInterface* connection_pool, | 713 virtual void InitSMConnection(SMConnectionPoolInterface* connection_pool, |
696 SMInterface* sm_interface, | 714 SMInterface* sm_interface, |
697 EpollServer* epoll_server, | 715 EpollServer* epoll_server, |
698 int fd, | 716 int fd, |
699 string server_ip, | 717 string server_ip, |
700 string server_port, | 718 string server_port, |
| 719 string remote_ip, |
701 bool use_ssl) = 0; | 720 bool use_ssl) = 0; |
702 virtual size_t ProcessReadInput(const char* data, size_t len) = 0; | 721 virtual size_t ProcessReadInput(const char* data, size_t len) = 0; |
703 virtual size_t ProcessWriteInput(const char* data, size_t len) = 0; | 722 virtual size_t ProcessWriteInput(const char* data, size_t len) = 0; |
704 virtual void SetStreamID(uint32 stream_id) = 0; | 723 virtual void SetStreamID(uint32 stream_id) = 0; |
705 virtual bool MessageFullyRead() const = 0; | 724 virtual bool MessageFullyRead() const = 0; |
706 virtual bool Error() const = 0; | 725 virtual bool Error() const = 0; |
707 virtual const char* ErrorAsString() const = 0; | 726 virtual const char* ErrorAsString() const = 0; |
708 virtual void Reset() = 0; | 727 virtual void Reset() = 0; |
709 virtual void ResetForNewInterface(int32 server_idx) = 0; | 728 virtual void ResetForNewInterface(int32 server_idx) = 0; |
710 // ResetForNewConnection is used for interfaces which control SMConnection | 729 // ResetForNewConnection is used for interfaces which control SMConnection |
(...skipping 23 matching lines...) Expand all Loading... |
734 class SMConnectionInterface { | 753 class SMConnectionInterface { |
735 public: | 754 public: |
736 virtual ~SMConnectionInterface() {} | 755 virtual ~SMConnectionInterface() {} |
737 virtual void ReadyToSend() = 0; | 756 virtual void ReadyToSend() = 0; |
738 virtual EpollServer* epoll_server() = 0; | 757 virtual EpollServer* epoll_server() = 0; |
739 }; | 758 }; |
740 | 759 |
741 class HttpSM; | 760 class HttpSM; |
742 class SMConnection; | 761 class SMConnection; |
743 | 762 |
744 typedef list<DataFrame> OutputList; | 763 typedef list<DataFrame*> OutputList; |
745 | 764 |
746 class SMConnectionPoolInterface { | 765 class SMConnectionPoolInterface { |
747 public: | 766 public: |
748 virtual ~SMConnectionPoolInterface() {} | 767 virtual ~SMConnectionPoolInterface() {} |
749 // SMConnections will use this: | 768 // SMConnections will use this: |
750 virtual void SMConnectionDone(SMConnection* connection) = 0; | 769 virtual void SMConnectionDone(SMConnection* connection) = 0; |
751 }; | 770 }; |
752 | 771 |
753 SMInterface* NewStreamerSM(SMConnection* connection, | 772 SMInterface* NewStreamerSM(SMConnection* connection, |
754 SMInterface* sm_interface, | 773 SMInterface* sm_interface, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 ssl_state_(ssl_state), | 808 ssl_state_(ssl_state), |
790 memory_cache_(memory_cache), | 809 memory_cache_(memory_cache), |
791 acceptor_(acceptor), | 810 acceptor_(acceptor), |
792 read_buffer_(4096*10), | 811 read_buffer_(4096*10), |
793 sm_spdy_interface_(NULL), | 812 sm_spdy_interface_(NULL), |
794 sm_http_interface_(NULL), | 813 sm_http_interface_(NULL), |
795 sm_streamer_interface_(NULL), | 814 sm_streamer_interface_(NULL), |
796 sm_interface_(NULL), | 815 sm_interface_(NULL), |
797 log_prefix_(log_prefix), | 816 log_prefix_(log_prefix), |
798 max_bytes_sent_per_dowrite_(4096), | 817 max_bytes_sent_per_dowrite_(4096), |
799 ssl_(NULL) | 818 ssl_(NULL), |
| 819 last_read_time_(0) |
800 {} | 820 {} |
801 | 821 |
802 int fd_; | 822 int fd_; |
803 int events_; | 823 int events_; |
804 | 824 |
805 bool registered_in_epoll_server_; | 825 bool registered_in_epoll_server_; |
806 bool initialized_; | 826 bool initialized_; |
807 bool protocol_detected_; | 827 bool protocol_detected_; |
808 bool connection_complete_; | 828 bool connection_complete_; |
809 | 829 |
(...skipping 11 matching lines...) Expand all Loading... |
821 SMInterface* sm_spdy_interface_; | 841 SMInterface* sm_spdy_interface_; |
822 SMInterface* sm_http_interface_; | 842 SMInterface* sm_http_interface_; |
823 SMInterface* sm_streamer_interface_; | 843 SMInterface* sm_streamer_interface_; |
824 SMInterface* sm_interface_; | 844 SMInterface* sm_interface_; |
825 string log_prefix_; | 845 string log_prefix_; |
826 | 846 |
827 size_t max_bytes_sent_per_dowrite_; | 847 size_t max_bytes_sent_per_dowrite_; |
828 | 848 |
829 SSL* ssl_; | 849 SSL* ssl_; |
830 public: | 850 public: |
| 851 time_t last_read_time_; |
831 string server_ip_; | 852 string server_ip_; |
832 string server_port_; | 853 string server_port_; |
833 | 854 |
834 EpollServer* epoll_server() { return epoll_server_; } | 855 EpollServer* epoll_server() { return epoll_server_; } |
835 OutputList* output_list() { return &output_list_; } | 856 OutputList* output_list() { return &output_list_; } |
836 MemoryCache* memory_cache() { return memory_cache_; } | 857 MemoryCache* memory_cache() { return memory_cache_; } |
837 void ReadyToSend() { | 858 void ReadyToSend() { |
838 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 859 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
839 << "Setting ready to send: EPOLLIN | EPOLLOUT"; | 860 << "Setting ready to send: EPOLLIN | EPOLLOUT"; |
840 epoll_server_->SetFDReady(fd_, EPOLLIN | EPOLLOUT); | 861 epoll_server_->SetFDReady(fd_, EPOLLIN | EPOLLOUT); |
841 } | 862 } |
842 void EnqueueDataFrame(const DataFrame& df) { | 863 void EnqueueDataFrame(DataFrame* df) { |
843 output_list_.push_back(df); | 864 output_list_.push_back(df); |
844 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "EnqueueDataFrame: " | 865 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "EnqueueDataFrame: " |
845 << "size = " << df.size << ": Setting FD ready."; | 866 << "size = " << df->size << ": Setting FD ready."; |
846 ReadyToSend(); | 867 ReadyToSend(); |
847 } | 868 } |
848 int fd() { return fd_; } | 869 int fd() { return fd_; } |
849 | 870 |
850 public: | 871 public: |
851 ~SMConnection() { | 872 ~SMConnection() { |
852 if (initialized()) { | 873 if (initialized()) { |
853 Reset(); | 874 Reset(); |
854 } | 875 } |
855 } | 876 } |
856 static SMConnection* NewSMConnection(EpollServer* epoll_server, | 877 static SMConnection* NewSMConnection(EpollServer* epoll_server, |
857 SSLState *ssl_state, | 878 SSLState *ssl_state, |
858 MemoryCache* memory_cache, | 879 MemoryCache* memory_cache, |
859 FlipAcceptor *acceptor, | 880 FlipAcceptor *acceptor, |
860 string log_prefix) { | 881 string log_prefix) { |
861 return new SMConnection(epoll_server, ssl_state, memory_cache, | 882 return new SMConnection(epoll_server, ssl_state, memory_cache, |
862 acceptor, log_prefix); | 883 acceptor, log_prefix); |
863 } | 884 } |
864 | 885 |
865 bool initialized() const { return initialized_; } | 886 bool initialized() const { return initialized_; } |
866 string client_ip() const { return client_ip_; } | 887 string client_ip() const { return client_ip_; } |
867 | 888 |
868 void InitSMConnection(SMConnectionPoolInterface* connection_pool, | 889 void InitSMConnection(SMConnectionPoolInterface* connection_pool, |
869 SMInterface* sm_interface, | 890 SMInterface* sm_interface, |
870 EpollServer* epoll_server, | 891 EpollServer* epoll_server, |
871 int fd, | 892 int fd, |
872 string server_ip, | 893 string server_ip, |
873 string server_port, | 894 string server_port, |
| 895 string remote_ip, |
874 bool use_ssl) { | 896 bool use_ssl) { |
875 if (initialized_) { | 897 if (initialized_) { |
876 LOG(FATAL) << "Attempted to initialize already initialized server"; | 898 LOG(FATAL) << "Attempted to initialize already initialized server"; |
877 return; | 899 return; |
878 } | 900 } |
879 | 901 |
| 902 client_ip_ = remote_ip; |
| 903 |
880 if (fd == -1) { | 904 if (fd == -1) { |
881 // If fd == -1, then we are initializing a new connection that will | 905 // If fd == -1, then we are initializing a new connection that will |
882 // connect to the backend. | 906 // connect to the backend. |
883 // | 907 // |
884 // ret: -1 == error | 908 // ret: -1 == error |
885 // 0 == connection in progress | 909 // 0 == connection in progress |
886 // 1 == connection complete | 910 // 1 == connection complete |
887 // TODO: is_numeric_host_address value needs to be detected | 911 // TODO: is_numeric_host_address value needs to be detected |
888 server_ip_ = server_ip; | 912 server_ip_ = server_ip; |
889 server_port_ = server_port; | 913 server_port_ = server_port; |
(...skipping 24 matching lines...) Expand all Loading... |
914 epoll_server_->UnregisterFD(fd_); | 938 epoll_server_->UnregisterFD(fd_); |
915 } | 939 } |
916 if (fd_ != -1) { | 940 if (fd_ != -1) { |
917 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 941 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
918 << "Closing pre-existing fd"; | 942 << "Closing pre-existing fd"; |
919 close(fd_); | 943 close(fd_); |
920 fd_ = -1; | 944 fd_ = -1; |
921 } | 945 } |
922 | 946 |
923 fd_ = fd; | 947 fd_ = fd; |
924 struct sockaddr sock_addr; | |
925 socklen_t addr_size = sizeof(sock_addr); | |
926 addr_size = sizeof(sock_addr); | |
927 int res = getsockname(fd_, &sock_addr, &addr_size); | |
928 if (res < 0) { | |
929 LOG(ERROR) << "Could not get socket address for fd " << fd_ | |
930 << ": getsockname: " << strerror(errno); | |
931 } else { | |
932 struct sockaddr_in *sock_addr_in = (struct sockaddr_in *)&sock_addr; | |
933 char ip[16]; | |
934 snprintf(ip, sizeof(ip), "%d.%d.%d.%d", | |
935 IPV4_PRINTABLE_FORMAT(sock_addr_in->sin_addr.s_addr)); | |
936 client_ip_ = ip; | |
937 } | |
938 } | 948 } |
939 | 949 |
940 registered_in_epoll_server_ = false; | 950 registered_in_epoll_server_ = false; |
| 951 // Set the last read time here as the idle checker will start from |
| 952 // now. |
| 953 last_read_time_ = time(NULL); |
941 initialized_ = true; | 954 initialized_ = true; |
942 | 955 |
943 connection_pool_ = connection_pool; | 956 connection_pool_ = connection_pool; |
944 epoll_server_ = epoll_server; | 957 epoll_server_ = epoll_server; |
945 | 958 |
946 if (sm_interface) { | 959 if (sm_interface) { |
947 sm_interface_ = sm_interface; | 960 sm_interface_ = sm_interface; |
948 protocol_detected_ = true; | 961 protocol_detected_ = true; |
949 } | 962 } |
950 | 963 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 } | 997 } |
985 // If we wrote some data, return that count. Otherwise | 998 // If we wrote some data, return that count. Otherwise |
986 // return the stall error. | 999 // return the stall error. |
987 return bytes_written > 0 ? bytes_written : rv; | 1000 return bytes_written > 0 ? bytes_written : rv; |
988 } | 1001 } |
989 bytes_written += rv; | 1002 bytes_written += rv; |
990 len -= rv; | 1003 len -= rv; |
991 if (rv != chunksize) | 1004 if (rv != chunksize) |
992 break; // If we couldn't write everything, we're implicitly stalled | 1005 break; // If we couldn't write everything, we're implicitly stalled |
993 } | 1006 } |
| 1007 if (!(flags & MSG_MORE)) { |
| 1008 int state = 0; |
| 1009 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); |
| 1010 state = 1; |
| 1011 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); |
| 1012 } |
994 } else { | 1013 } else { |
995 bytes_written = send(fd_, data, len, flags); | 1014 bytes_written = send(fd_, data, len, flags); |
996 } | 1015 } |
997 return bytes_written; | 1016 return bytes_written; |
998 } | 1017 } |
999 | 1018 |
1000 // the following are from the EpollCallbackInterface | 1019 // the following are from the EpollCallbackInterface |
1001 virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) { | 1020 virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) { |
1002 registered_in_epoll_server_ = true; | 1021 registered_in_epoll_server_ = true; |
1003 } | 1022 } |
1004 virtual void OnModification(int fd, int event_mask) { } | 1023 virtual void OnModification(int fd, int event_mask) { } |
1005 virtual void OnEvent(int fd, EpollEvent* event) { | 1024 virtual void OnEvent(int fd, EpollEvent* event) { |
1006 events_ |= event->in_events; | 1025 events_ |= event->in_events; |
1007 HandleEvents(); | 1026 HandleEvents(); |
1008 if (events_) { | 1027 if (events_) { |
1009 event->out_ready_mask = events_; | 1028 event->out_ready_mask = events_; |
1010 events_ = 0; | 1029 events_ = 0; |
1011 } | 1030 } |
1012 } | 1031 } |
1013 virtual void OnUnregistration(int fd, bool replaced) { | 1032 virtual void OnUnregistration(int fd, bool replaced) { |
1014 registered_in_epoll_server_ = false; | 1033 registered_in_epoll_server_ = false; |
1015 } | 1034 } |
1016 virtual void OnShutdown(EpollServer* eps, int fd) { | 1035 virtual void OnShutdown(EpollServer* eps, int fd) { |
1017 Cleanup("OnShutdown"); | 1036 Cleanup("OnShutdown"); |
1018 return; | 1037 return; |
1019 } | 1038 } |
1020 | 1039 |
1021 void Cleanup(const char* cleanup) { | 1040 void Cleanup(const char* cleanup) { |
1022 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Cleanup"; | 1041 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Cleanup: " << cleanup; |
1023 if (!initialized_) { | 1042 if (!initialized_) { |
1024 return; | 1043 return; |
1025 } | 1044 } |
1026 Reset(); | 1045 Reset(); |
1027 if (connection_pool_) { | 1046 if (connection_pool_) { |
1028 connection_pool_->SMConnectionDone(this); | 1047 connection_pool_->SMConnectionDone(this); |
1029 } | 1048 } |
1030 if (sm_interface_) { | 1049 if (sm_interface_) { |
1031 sm_interface_->ResetForNewConnection(); | 1050 sm_interface_->ResetForNewConnection(); |
1032 } | 1051 } |
| 1052 last_read_time_ = 0; |
1033 } | 1053 } |
1034 | 1054 |
1035 private: | 1055 private: |
1036 void HandleEvents() { | 1056 void HandleEvents() { |
1037 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Received: " | 1057 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Received: " |
1038 << EpollServer::EventMaskToString(events_).c_str(); | 1058 << EpollServer::EventMaskToString(events_).c_str(); |
1039 | 1059 |
1040 if (events_ & EPOLLIN) { | 1060 if (events_ & EPOLLIN) { |
1041 if (!DoRead()) | 1061 if (!DoRead()) |
1042 goto handle_close_or_error; | 1062 goto handle_close_or_error; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 continue; | 1145 continue; |
1126 default: | 1146 default: |
1127 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1147 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
1128 << "While calling recv, got error: " | 1148 << "While calling recv, got error: " |
1129 << (ssl_?"(ssl error)":strerror(stored_errno)); | 1149 << (ssl_?"(ssl error)":strerror(stored_errno)); |
1130 goto error_or_close; | 1150 goto error_or_close; |
1131 } | 1151 } |
1132 } else if (bytes_read > 0) { | 1152 } else if (bytes_read > 0) { |
1133 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "read " << bytes_read | 1153 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "read " << bytes_read |
1134 << " bytes"; | 1154 << " bytes"; |
| 1155 last_read_time_ = time(NULL); |
1135 if (!protocol_detected_) { | 1156 if (!protocol_detected_) { |
1136 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { | 1157 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { |
1137 // Http Server | 1158 // Http Server |
1138 protocol_detected_ = true; | 1159 protocol_detected_ = true; |
1139 if (!sm_http_interface_) { | 1160 if (!sm_http_interface_) { |
1140 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1161 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
1141 << "Created HTTP interface."; | 1162 << "Created HTTP interface."; |
1142 sm_http_interface_ = NewHttpSM(this, NULL, epoll_server_, | 1163 sm_http_interface_ = NewHttpSM(this, NULL, epoll_server_, |
1143 memory_cache_, acceptor_); | 1164 memory_cache_, acceptor_); |
1144 } else { | 1165 } else { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1296 << output_list_.size(); | 1317 << output_list_.size(); |
1297 if (bytes_sent >= max_bytes_sent_per_dowrite_) { | 1318 if (bytes_sent >= max_bytes_sent_per_dowrite_) { |
1298 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1319 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
1299 << " byte sent >= max bytes sent per write: Setting EPOLLOUT"; | 1320 << " byte sent >= max bytes sent per write: Setting EPOLLOUT"; |
1300 events_ |= EPOLLOUT; | 1321 events_ |= EPOLLOUT; |
1301 break; | 1322 break; |
1302 } | 1323 } |
1303 if (sm_interface_ && output_list_.size() < 2) { | 1324 if (sm_interface_ && output_list_.size() < 2) { |
1304 sm_interface_->GetOutput(); | 1325 sm_interface_->GetOutput(); |
1305 } | 1326 } |
1306 DataFrame& data_frame = output_list_.front(); | 1327 DataFrame* data_frame = output_list_.front(); |
1307 const char* bytes = data_frame.data; | 1328 const char* bytes = data_frame->data; |
1308 int size = data_frame.size; | 1329 int size = data_frame->size; |
1309 bytes += data_frame.index; | 1330 bytes += data_frame->index; |
1310 size -= data_frame.index; | 1331 size -= data_frame->index; |
1311 DCHECK_GE(size, 0); | 1332 DCHECK_GE(size, 0); |
1312 if (size <= 0) { | 1333 if (size <= 0) { |
1313 // Empty data frame. Indicates end of data from client. | 1334 // Empty data frame. Indicates end of data from client. |
1314 // Uncork the socket. | 1335 // Uncork the socket. |
1315 int state = 0; | 1336 int state = 0; |
1316 VLOG(2) << log_prefix_ << "Empty data frame, uncorking socket."; | 1337 VLOG(2) << log_prefix_ << "Empty data frame, uncorking socket."; |
1317 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); | 1338 setsockopt( fd_, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) ); |
1318 data_frame.MaybeDelete(); | |
1319 output_list_.pop_front(); | 1339 output_list_.pop_front(); |
| 1340 delete data_frame; |
1320 continue; | 1341 continue; |
1321 } | 1342 } |
1322 | 1343 |
1323 flags = MSG_NOSIGNAL | MSG_DONTWAIT; | 1344 flags = MSG_NOSIGNAL | MSG_DONTWAIT; |
1324 if (output_list_.size() > 1) { | 1345 if (output_list_.size() > 1) { |
1325 VLOG(2) << log_prefix_ << "Outlist size: " << output_list_.size() | 1346 VLOG(2) << log_prefix_ << "Outlist size: " << output_list_.size() |
1326 << ": Adding MSG_MORE flag"; | 1347 << ": Adding MSG_MORE flag"; |
1327 flags |= MSG_MORE; | 1348 flags |= MSG_MORE; |
1328 } | 1349 } |
1329 VLOG(2) << log_prefix_ << "Attempting to send " << size << " bytes."; | 1350 VLOG(2) << log_prefix_ << "Attempting to send " << size << " bytes."; |
(...skipping 12 matching lines...) Expand all Loading... |
1342 continue; | 1363 continue; |
1343 default: | 1364 default: |
1344 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1365 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
1345 << "While calling send, got error: " << stored_errno | 1366 << "While calling send, got error: " << stored_errno |
1346 << ": " << (ssl_?"":strerror(stored_errno)); | 1367 << ": " << (ssl_?"":strerror(stored_errno)); |
1347 goto error_or_close; | 1368 goto error_or_close; |
1348 } | 1369 } |
1349 } else if (bytes_written > 0) { | 1370 } else if (bytes_written > 0) { |
1350 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Wrote: " | 1371 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Wrote: " |
1351 << bytes_written << " bytes"; | 1372 << bytes_written << " bytes"; |
1352 data_frame.index += bytes_written; | 1373 data_frame->index += bytes_written; |
1353 bytes_sent += bytes_written; | 1374 bytes_sent += bytes_written; |
1354 continue; | 1375 continue; |
1355 } else if (bytes_written == -2) { | 1376 } else if (bytes_written == -2) { |
1356 // -2 handles SSL_ERROR_WANT_* errors | 1377 // -2 handles SSL_ERROR_WANT_* errors |
1357 events_ &= ~EPOLLOUT; | 1378 events_ &= ~EPOLLOUT; |
1358 goto done; | 1379 goto done; |
1359 } | 1380 } |
1360 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 1381 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
1361 << "0 bytes written with send call."; | 1382 << "0 bytes written with send call."; |
1362 goto error_or_close; | 1383 goto error_or_close; |
(...skipping 14 matching lines...) Expand all Loading... |
1377 return os; | 1398 return os; |
1378 } | 1399 } |
1379 | 1400 |
1380 void Reset() { | 1401 void Reset() { |
1381 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Resetting"; | 1402 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Resetting"; |
1382 if (ssl_) { | 1403 if (ssl_) { |
1383 SSL_shutdown(ssl_); | 1404 SSL_shutdown(ssl_); |
1384 PrintSslError(); | 1405 PrintSslError(); |
1385 SSL_free(ssl_); | 1406 SSL_free(ssl_); |
1386 PrintSslError(); | 1407 PrintSslError(); |
| 1408 ssl_ = NULL; |
1387 } | 1409 } |
1388 if (registered_in_epoll_server_) { | 1410 if (registered_in_epoll_server_) { |
1389 epoll_server_->UnregisterFD(fd_); | 1411 epoll_server_->UnregisterFD(fd_); |
1390 registered_in_epoll_server_ = false; | 1412 registered_in_epoll_server_ = false; |
1391 } | 1413 } |
1392 if (fd_ >= 0) { | 1414 if (fd_ >= 0) { |
1393 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Closing connection"; | 1415 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Closing connection"; |
1394 close(fd_); | 1416 close(fd_); |
1395 fd_ = -1; | 1417 fd_ = -1; |
1396 } | 1418 } |
1397 read_buffer_.Clear(); | 1419 read_buffer_.Clear(); |
1398 initialized_ = false; | 1420 initialized_ = false; |
1399 protocol_detected_ = false; | 1421 protocol_detected_ = false; |
1400 events_ = 0; | 1422 events_ = 0; |
| 1423 for (list<DataFrame*>::iterator i = |
| 1424 output_list_.begin(); |
| 1425 i != output_list_.end(); |
| 1426 ++i) { |
| 1427 delete *i; |
| 1428 } |
1401 output_list_.clear(); | 1429 output_list_.clear(); |
1402 } | 1430 } |
1403 | 1431 |
1404 }; | 1432 }; |
1405 | 1433 |
1406 //////////////////////////////////////////////////////////////////////////////// | 1434 //////////////////////////////////////////////////////////////////////////////// |
1407 | 1435 |
1408 class OutputOrdering { | 1436 class OutputOrdering { |
1409 public: | 1437 public: |
1410 typedef list<MemCacheIter> PriorityRing; | 1438 typedef list<MemCacheIter> PriorityRing; |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 | 1660 |
1633 void InitSMInterface(SMInterface* sm_http_interface, | 1661 void InitSMInterface(SMInterface* sm_http_interface, |
1634 int32 server_idx) { } | 1662 int32 server_idx) { } |
1635 | 1663 |
1636 void InitSMConnection(SMConnectionPoolInterface* connection_pool, | 1664 void InitSMConnection(SMConnectionPoolInterface* connection_pool, |
1637 SMInterface* sm_interface, | 1665 SMInterface* sm_interface, |
1638 EpollServer* epoll_server, | 1666 EpollServer* epoll_server, |
1639 int fd, | 1667 int fd, |
1640 string server_ip, | 1668 string server_ip, |
1641 string server_port, | 1669 string server_port, |
| 1670 string remote_ip, |
1642 bool use_ssl) { | 1671 bool use_ssl) { |
1643 VLOG(2) << ACCEPTOR_CLIENT_IDENT | 1672 VLOG(2) << ACCEPTOR_CLIENT_IDENT |
1644 << "SpdySM: Initializing server connection."; | 1673 << "SpdySM: Initializing server connection."; |
1645 connection_->InitSMConnection(connection_pool, sm_interface, | 1674 connection_->InitSMConnection(connection_pool, sm_interface, |
1646 epoll_server, fd, server_ip, server_port, | 1675 epoll_server, fd, server_ip, server_port, |
1647 use_ssl); | 1676 remote_ip, use_ssl); |
1648 } | 1677 } |
1649 | 1678 |
1650 private: | 1679 private: |
1651 virtual void OnError(SpdyFramer* framer) { | 1680 virtual void OnError(SpdyFramer* framer) { |
1652 /* do nothing with this right now */ | 1681 /* do nothing with this right now */ |
1653 } | 1682 } |
1654 | 1683 |
1655 SMInterface* NewConnectionInterface() { | 1684 SMInterface* NewConnectionInterface() { |
1656 SMConnection* server_connection = | 1685 SMConnection* server_connection = |
1657 SMConnection::NewSMConnection(epoll_server_, NULL, | 1686 SMConnection::NewSMConnection(epoll_server_, NULL, |
(...skipping 25 matching lines...) Expand all Loading... |
1683 server_idx = unused_server_interface_list.back(); | 1712 server_idx = unused_server_interface_list.back(); |
1684 unused_server_interface_list.pop_back(); | 1713 unused_server_interface_list.pop_back(); |
1685 sm_http_interface = server_interface_list.at(server_idx); | 1714 sm_http_interface = server_interface_list.at(server_idx); |
1686 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reusing connection on " | 1715 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reusing connection on " |
1687 << "index: " << server_idx; | 1716 << "index: " << server_idx; |
1688 } | 1717 } |
1689 | 1718 |
1690 sm_http_interface->InitSMInterface(this, server_idx); | 1719 sm_http_interface->InitSMInterface(this, server_idx); |
1691 sm_http_interface->InitSMConnection(NULL, sm_http_interface, | 1720 sm_http_interface->InitSMConnection(NULL, sm_http_interface, |
1692 epoll_server_, -1, | 1721 epoll_server_, -1, |
1693 server_ip, server_port, false); | 1722 server_ip, server_port, "", false); |
1694 | 1723 |
1695 return sm_http_interface; | 1724 return sm_http_interface; |
1696 } | 1725 } |
1697 | 1726 |
1698 int SpdyHandleNewStream(const SpdyControlFrame* frame, | 1727 int SpdyHandleNewStream(const SpdyControlFrame* frame, |
1699 string *http_data, | 1728 string &http_data, |
1700 bool *is_https_scheme) | 1729 bool *is_https_scheme) |
1701 { | 1730 { |
1702 bool parsed_headers = false; | 1731 bool parsed_headers = false; |
1703 SpdyHeaderBlock headers; | 1732 SpdyHeaderBlock headers; |
1704 const SpdySynStreamControlFrame* syn_stream = | 1733 const SpdySynStreamControlFrame* syn_stream = |
1705 reinterpret_cast<const SpdySynStreamControlFrame*>(frame); | 1734 reinterpret_cast<const SpdySynStreamControlFrame*>(frame); |
1706 | 1735 |
1707 *is_https_scheme = false; | 1736 *is_https_scheme = false; |
1708 parsed_headers = spdy_framer_->ParseHeaderBlock(frame, &headers); | 1737 parsed_headers = spdy_framer_->ParseHeaderBlock(frame, &headers); |
1709 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSyn(" | 1738 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: OnSyn(" |
(...skipping 26 matching lines...) Expand all Loading... |
1736 string host = UrlUtilities::GetUrlHost(url->second); | 1765 string host = UrlUtilities::GetUrlHost(url->second); |
1737 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second | 1766 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second |
1738 << " " << uri; | 1767 << " " << uri; |
1739 string filename = EncodeURL(uri, host, method->second); | 1768 string filename = EncodeURL(uri, host, method->second); |
1740 NewStream(syn_stream->stream_id(), | 1769 NewStream(syn_stream->stream_id(), |
1741 reinterpret_cast<const SpdySynStreamControlFrame*>(frame)-> | 1770 reinterpret_cast<const SpdySynStreamControlFrame*>(frame)-> |
1742 priority(), | 1771 priority(), |
1743 filename); | 1772 filename); |
1744 } else { | 1773 } else { |
1745 SpdyHeaderBlock::iterator version = headers.find("version"); | 1774 SpdyHeaderBlock::iterator version = headers.find("version"); |
1746 *http_data += method->second + " " + uri + " " + version->second + "\r\n"; | 1775 http_data += method->second + " " + uri + " " + version->second + "\r\n"; |
1747 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second << " " | 1776 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Request: " << method->second << " " |
1748 << uri << " " << version->second; | 1777 << uri << " " << version->second; |
1749 for (SpdyHeaderBlock::iterator i = headers.begin(); | 1778 for (SpdyHeaderBlock::iterator i = headers.begin(); |
1750 i != headers.end(); ++i) { | 1779 i != headers.end(); ++i) { |
1751 *http_data += i->first + ": " + i->second + "\r\n"; | 1780 http_data += i->first + ": " + i->second + "\r\n"; |
1752 VLOG(2) << ACCEPTOR_CLIENT_IDENT << i->first.c_str() << ":" | 1781 VLOG(2) << ACCEPTOR_CLIENT_IDENT << i->first.c_str() << ":" |
1753 << i->second.c_str(); | 1782 << i->second.c_str(); |
1754 } | 1783 } |
1755 if (g_proxy_config.forward_ip_header_enabled_) { | 1784 if (g_proxy_config.forward_ip_header_enabled_) { |
1756 // X-Client-Cluster-IP header | 1785 // X-Client-Cluster-IP header |
1757 *http_data += g_proxy_config.forward_ip_header_ + ": " + | 1786 http_data += g_proxy_config.forward_ip_header_ + ": " + |
1758 connection_->client_ip() + "\r\n"; | 1787 connection_->client_ip() + "\r\n"; |
1759 } | 1788 } |
1760 *http_data += "\r\n"; | 1789 http_data += "\r\n"; |
1761 } | 1790 } |
1762 | 1791 |
1763 VLOG(3) << ACCEPTOR_CLIENT_IDENT << "SpdySM: HTTP Request:\n" << http_data; | 1792 VLOG(3) << ACCEPTOR_CLIENT_IDENT << "SpdySM: HTTP Request:\n" << http_data; |
1764 return 1; | 1793 return 1; |
1765 } | 1794 } |
1766 | 1795 |
1767 virtual void OnControl(const SpdyControlFrame* frame) { | 1796 virtual void OnControl(const SpdyControlFrame* frame) { |
1768 SpdyHeaderBlock headers; | 1797 SpdyHeaderBlock headers; |
1769 bool parsed_headers = false; | 1798 bool parsed_headers = false; |
1770 switch (frame->type()) { | 1799 switch (frame->type()) { |
1771 case SYN_STREAM: | 1800 case SYN_STREAM: |
1772 { | 1801 { |
1773 const SpdySynStreamControlFrame* syn_stream = | 1802 const SpdySynStreamControlFrame* syn_stream = |
1774 reinterpret_cast<const SpdySynStreamControlFrame*>(frame); | 1803 reinterpret_cast<const SpdySynStreamControlFrame*>(frame); |
1775 | 1804 |
1776 string http_data; | 1805 string http_data; |
1777 bool is_https_scheme; | 1806 bool is_https_scheme; |
1778 int ret = SpdyHandleNewStream(frame, &http_data, &is_https_scheme); | 1807 int ret = SpdyHandleNewStream(frame, http_data, &is_https_scheme); |
1779 if (!ret) { | 1808 if (!ret) { |
1780 LOG(ERROR) << "SpdySM: Could not convert spdy into http."; | 1809 LOG(ERROR) << "SpdySM: Could not convert spdy into http."; |
1781 break; | 1810 break; |
1782 } | 1811 } |
1783 | 1812 |
1784 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { | 1813 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) { |
1785 string server_ip; | 1814 string server_ip; |
1786 string server_port; | 1815 string server_port; |
1787 if (is_https_scheme) { | 1816 if (is_https_scheme) { |
1788 server_ip = acceptor_->https_server_ip_; | 1817 server_ip = acceptor_->https_server_ip_; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1872 next_outgoing_stream_id_ = 2; | 1901 next_outgoing_stream_id_ = 2; |
1873 } | 1902 } |
1874 | 1903 |
1875 // SMInterface's Cleanup is currently only called by SMConnection after a | 1904 // SMInterface's Cleanup is currently only called by SMConnection after a |
1876 // protocol message as been fully read. Spdy's SMInterface does not need | 1905 // protocol message as been fully read. Spdy's SMInterface does not need |
1877 // to do any cleanup at this time. | 1906 // to do any cleanup at this time. |
1878 // TODO (klindsay) This method is probably not being used properly and | 1907 // TODO (klindsay) This method is probably not being used properly and |
1879 // some logic review and method renaming is probably in order. | 1908 // some logic review and method renaming is probably in order. |
1880 void Cleanup() {} | 1909 void Cleanup() {} |
1881 | 1910 |
1882 // Send a settings frame and possibly some NOOP packets to force | 1911 // Send a settings frame |
1883 // opening of cwnd | |
1884 int PostAcceptHook() { | 1912 int PostAcceptHook() { |
1885 ssize_t bytes_written; | 1913 ssize_t bytes_written; |
1886 spdy::SpdySettings settings; | 1914 spdy::SpdySettings settings; |
1887 spdy::SettingsFlagsAndId settings_id(0); | 1915 spdy::SettingsFlagsAndId settings_id(0); |
1888 settings_id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); | 1916 settings_id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); |
1889 settings.push_back(spdy::SpdySetting(settings_id, 100)); | 1917 settings.push_back(spdy::SpdySetting(settings_id, 100)); |
1890 scoped_ptr<SpdySettingsControlFrame> | 1918 scoped_ptr<SpdySettingsControlFrame> |
1891 settings_frame(spdy_framer_->CreateSettings(settings)); | 1919 settings_frame(spdy_framer_->CreateSettings(settings)); |
1892 | 1920 |
1893 char* bytes = settings_frame->data(); | 1921 char* bytes = settings_frame->data(); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2035 string original_url = headers.GetHeader("X-Original-Url").as_string(); | 2063 string original_url = headers.GetHeader("X-Original-Url").as_string(); |
2036 block["path"] = UrlUtilities::GetUrlPath(original_url); | 2064 block["path"] = UrlUtilities::GetUrlPath(original_url); |
2037 } else { | 2065 } else { |
2038 block["path"] = headers.request_uri().as_string(); | 2066 block["path"] = headers.request_uri().as_string(); |
2039 } | 2067 } |
2040 CopyHeaders(block, headers); | 2068 CopyHeaders(block, headers); |
2041 | 2069 |
2042 SpdySynStreamControlFrame* fsrcf = | 2070 SpdySynStreamControlFrame* fsrcf = |
2043 spdy_framer_->CreateSynStream(stream_id, 0, 0, CONTROL_FLAG_NONE, true, | 2071 spdy_framer_->CreateSynStream(stream_id, 0, 0, CONTROL_FLAG_NONE, true, |
2044 &block); | 2072 &block); |
2045 DataFrame df; | 2073 SpdyFrameDataFrame* df = new SpdyFrameDataFrame; |
2046 df.size = fsrcf->length() + SpdyFrame::size(); | 2074 df->size = fsrcf->length() + SpdyFrame::size(); |
2047 size_t df_size = df.size; | 2075 size_t df_size = df->size; |
2048 df.data = fsrcf->data(); | 2076 df->data = fsrcf->data(); |
2049 df.delete_when_done = true; | 2077 df->frame = fsrcf; |
| 2078 df->delete_when_done = true; |
2050 EnqueueDataFrame(df); | 2079 EnqueueDataFrame(df); |
2051 | 2080 |
2052 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynStreamheader " | 2081 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynStreamheader " |
2053 << stream_id; | 2082 << stream_id; |
2054 return df_size; | 2083 return df_size; |
2055 } | 2084 } |
2056 | 2085 |
2057 size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) { | 2086 size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) { |
2058 SpdyHeaderBlock block; | 2087 SpdyHeaderBlock block; |
2059 CopyHeaders(block, headers); | 2088 CopyHeaders(block, headers); |
2060 block["status"] = headers.response_code().as_string() + " " + | 2089 block["status"] = headers.response_code().as_string() + " " + |
2061 headers.response_reason_phrase().as_string(); | 2090 headers.response_reason_phrase().as_string(); |
2062 block["version"] = headers.response_version().as_string(); | 2091 block["version"] = headers.response_version().as_string(); |
2063 | 2092 |
2064 SpdySynReplyControlFrame* fsrcf = | 2093 SpdySynReplyControlFrame* fsrcf = |
2065 spdy_framer_->CreateSynReply(stream_id, CONTROL_FLAG_NONE, true, &block); | 2094 spdy_framer_->CreateSynReply(stream_id, CONTROL_FLAG_NONE, true, &block); |
2066 DataFrame df; | 2095 SpdyFrameDataFrame* df = new SpdyFrameDataFrame; |
2067 df.size = fsrcf->length() + SpdyFrame::size(); | 2096 df->size = fsrcf->length() + SpdyFrame::size(); |
2068 size_t df_size = df.size; | 2097 size_t df_size = df->size; |
2069 df.data = fsrcf->data(); | 2098 df->data = fsrcf->data(); |
2070 df.delete_when_done = true; | 2099 df->frame = fsrcf; |
| 2100 df->delete_when_done = true; |
2071 EnqueueDataFrame(df); | 2101 EnqueueDataFrame(df); |
2072 | 2102 |
2073 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynReplyheader " | 2103 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynReplyheader " |
2074 << stream_id; | 2104 << stream_id; |
2075 return df_size; | 2105 return df_size; |
2076 } | 2106 } |
2077 | 2107 |
2078 void SendDataFrameImpl(uint32 stream_id, const char* data, int64 len, | 2108 void SendDataFrameImpl(uint32 stream_id, const char* data, int64 len, |
2079 SpdyDataFlags flags, bool compress) { | 2109 SpdyDataFlags flags, bool compress) { |
2080 // Force compression off if disabled via command line. | 2110 // Force compression off if disabled via command line. |
2081 if (!FLAGS_use_compression) | 2111 if (!FLAGS_use_compression) |
2082 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_COMPRESSED); | 2112 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_COMPRESSED); |
2083 | 2113 |
2084 // TODO(mbelshe): We can't compress here - before going into the | 2114 // TODO(mbelshe): We can't compress here - before going into the |
2085 // priority queue. Compression needs to be done | 2115 // priority queue. Compression needs to be done |
2086 // with late binding. | 2116 // with late binding. |
2087 | |
2088 if (len == 0) { | 2117 if (len == 0) { |
2089 SpdyDataFrame* fdf = spdy_framer_->CreateDataFrame(stream_id, data, len, | 2118 SpdyDataFrame* fdf = spdy_framer_->CreateDataFrame(stream_id, data, len, |
2090 flags); | 2119 flags); |
2091 DataFrame df; | 2120 SpdyFrameDataFrame* df = new SpdyFrameDataFrame; |
2092 df.size = fdf->length() + SpdyFrame::size(); | 2121 df->size = fdf->length() + SpdyFrame::size(); |
2093 df.data = fdf->data(); | 2122 df->data = fdf->data(); |
2094 df.delete_when_done = true; | 2123 df->delete_when_done = true; |
2095 EnqueueDataFrame(df); | 2124 EnqueueDataFrame(df); |
2096 return; | 2125 return; |
2097 } | 2126 } |
2098 | 2127 |
2099 // Chop data frames into chunks so that one stream can't monopolize the | 2128 // Chop data frames into chunks so that one stream can't monopolize the |
2100 // output channel. | 2129 // output channel. |
2101 while(len > 0) { | 2130 while(len > 0) { |
2102 int64 size = std::min(len, static_cast<int64>(kSpdySegmentSize)); | 2131 int64 size = std::min(len, static_cast<int64>(kSpdySegmentSize)); |
2103 SpdyDataFlags chunk_flags = flags; | 2132 SpdyDataFlags chunk_flags = flags; |
2104 | 2133 |
2105 // If we chunked this block, and the FIN flag was set, there is more | 2134 // If we chunked this block, and the FIN flag was set, there is more |
2106 // data coming. So, remove the flag. | 2135 // data coming. So, remove the flag. |
2107 if ((size < len) && (flags & DATA_FLAG_FIN)) | 2136 if ((size < len) && (flags & DATA_FLAG_FIN)) |
2108 chunk_flags = static_cast<SpdyDataFlags>(chunk_flags & ~DATA_FLAG_FIN); | 2137 chunk_flags = static_cast<SpdyDataFlags>(chunk_flags & ~DATA_FLAG_FIN); |
2109 | 2138 |
2110 SpdyDataFrame* fdf = spdy_framer_->CreateDataFrame(stream_id, data, size, | 2139 SpdyDataFrame* fdf = spdy_framer_->CreateDataFrame(stream_id, data, size, |
2111 chunk_flags); | 2140 chunk_flags); |
2112 DataFrame df; | 2141 SpdyFrameDataFrame* df = new SpdyFrameDataFrame; |
2113 df.size = fdf->length() + SpdyFrame::size(); | 2142 df->size = fdf->length() + SpdyFrame::size(); |
2114 df.data = fdf->data(); | 2143 df->data = fdf->data(); |
2115 df.delete_when_done = true; | 2144 df->delete_when_done = true; |
2116 EnqueueDataFrame(df); | 2145 EnqueueDataFrame(df); |
2117 | 2146 |
2118 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending data frame " | 2147 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending data frame " |
2119 << stream_id << " [" << size << "] shrunk to " << fdf->length() | 2148 << stream_id << " [" << size << "] shrunk to " << fdf->length() |
2120 << ", flags=" << flags; | 2149 << ", flags=" << flags; |
2121 | 2150 |
2122 data += size; | 2151 data += size; |
2123 len -= size; | 2152 len -= size; |
2124 } | 2153 } |
2125 } | 2154 } |
2126 | 2155 |
2127 void EnqueueDataFrame(const DataFrame& df) { | 2156 void EnqueueDataFrame(DataFrame* df) { |
2128 connection_->EnqueueDataFrame(df); | 2157 connection_->EnqueueDataFrame(df); |
2129 } | 2158 } |
2130 | 2159 |
2131 void GetOutput() { | 2160 void GetOutput() { |
2132 while (client_output_list_->size() < 2) { | 2161 while (client_output_list_->size() < 2) { |
2133 MemCacheIter* mci = client_output_ordering_.GetIter(); | 2162 MemCacheIter* mci = client_output_ordering_.GetIter(); |
2134 if (mci == NULL) { | 2163 if (mci == NULL) { |
2135 VLOG(2) << ACCEPTOR_CLIENT_IDENT | 2164 VLOG(2) << ACCEPTOR_CLIENT_IDENT |
2136 << "SpdySM: GetOutput: nothing to output!?"; | 2165 << "SpdySM: GetOutput: nothing to output!?"; |
2137 return; | 2166 return; |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2316 sm_spdy_interface_ = sm_spdy_interface; | 2345 sm_spdy_interface_ = sm_spdy_interface; |
2317 server_idx_ = server_idx; | 2346 server_idx_ = server_idx; |
2318 } | 2347 } |
2319 | 2348 |
2320 void InitSMConnection(SMConnectionPoolInterface* connection_pool, | 2349 void InitSMConnection(SMConnectionPoolInterface* connection_pool, |
2321 SMInterface* sm_interface, | 2350 SMInterface* sm_interface, |
2322 EpollServer* epoll_server, | 2351 EpollServer* epoll_server, |
2323 int fd, | 2352 int fd, |
2324 string server_ip, | 2353 string server_ip, |
2325 string server_port, | 2354 string server_port, |
| 2355 string remote_ip, |
2326 bool use_ssl) | 2356 bool use_ssl) |
2327 { | 2357 { |
2328 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Initializing server " | 2358 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Initializing server " |
2329 << "connection."; | 2359 << "connection."; |
2330 connection_->InitSMConnection(connection_pool, sm_interface, | 2360 connection_->InitSMConnection(connection_pool, sm_interface, |
2331 epoll_server, fd, server_ip, server_port, | 2361 epoll_server, fd, server_ip, server_port, |
2332 use_ssl); | 2362 remote_ip, use_ssl); |
2333 } | 2363 } |
2334 | 2364 |
2335 size_t ProcessReadInput(const char* data, size_t len) { | 2365 size_t ProcessReadInput(const char* data, size_t len) { |
2336 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process read input: stream " | 2366 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process read input: stream " |
2337 << stream_id_; | 2367 << stream_id_; |
2338 return http_framer_->ProcessInput(data, len); | 2368 return http_framer_->ProcessInput(data, len); |
2339 } | 2369 } |
2340 | 2370 |
2341 size_t ProcessWriteInput(const char* data, size_t len) { | 2371 size_t ProcessWriteInput(const char* data, size_t len) { |
2342 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process write input: size " | 2372 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process write input: size " |
2343 << len << ": stream " << stream_id_; | 2373 << len << ": stream " << stream_id_; |
2344 char * dataPtr = new char[len]; | 2374 char * dataPtr = new char[len]; |
2345 memcpy(dataPtr, data, len); | 2375 memcpy(dataPtr, data, len); |
2346 DataFrame data_frame; | 2376 DataFrame* data_frame = new DataFrame; |
2347 data_frame.data = (const char *)dataPtr; | 2377 data_frame->data = (const char *)dataPtr; |
2348 data_frame.size = len; | 2378 data_frame->size = len; |
2349 data_frame.delete_when_done = true; | 2379 data_frame->delete_when_done = true; |
2350 connection_->EnqueueDataFrame(data_frame); | 2380 connection_->EnqueueDataFrame(data_frame); |
2351 return len; | 2381 return len; |
2352 } | 2382 } |
2353 | 2383 |
2354 bool MessageFullyRead() const { | 2384 bool MessageFullyRead() const { |
2355 return http_framer_->MessageFullyRead(); | 2385 return http_framer_->MessageFullyRead(); |
2356 } | 2386 } |
2357 | 2387 |
2358 void SetStreamID(uint32 stream_id) { | 2388 void SetStreamID(uint32 stream_id) { |
2359 stream_id_ = stream_id; | 2389 stream_id_ = stream_id; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2443 | 2473 |
2444 void SendDataFrame(uint32 stream_id, const char* data, int64 len, | 2474 void SendDataFrame(uint32 stream_id, const char* data, int64 len, |
2445 uint32 flags, bool compress) { | 2475 uint32 flags, bool compress) { |
2446 SendDataFrameImpl(stream_id, data, len, flags, compress); | 2476 SendDataFrameImpl(stream_id, data, len, flags, compress); |
2447 } | 2477 } |
2448 | 2478 |
2449 BalsaFrame* spdy_framer() { return http_framer_; } | 2479 BalsaFrame* spdy_framer() { return http_framer_; } |
2450 | 2480 |
2451 private: | 2481 private: |
2452 void SendEOFImpl(uint32 stream_id) { | 2482 void SendEOFImpl(uint32 stream_id) { |
2453 DataFrame df; | 2483 DataFrame* df = new DataFrame; |
2454 df.data = "0\r\n\r\n"; | 2484 df->data = "0\r\n\r\n"; |
2455 df.size = 5; | 2485 df->size = 5; |
2456 df.delete_when_done = false; | 2486 df->delete_when_done = false; |
2457 EnqueueDataFrame(df); | 2487 EnqueueDataFrame(df); |
2458 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { | 2488 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) { |
2459 Reset(); | 2489 Reset(); |
2460 } | 2490 } |
2461 } | 2491 } |
2462 | 2492 |
2463 void SendErrorNotFoundImpl(uint32 stream_id) { | 2493 void SendErrorNotFoundImpl(uint32 stream_id) { |
2464 BalsaHeaders my_headers; | 2494 BalsaHeaders my_headers; |
2465 my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found"); | 2495 my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found"); |
2466 my_headers.RemoveAllOfHeader("content-length"); | 2496 my_headers.RemoveAllOfHeader("content-length"); |
(...skipping 11 matching lines...) Expand all Loading... |
2478 my_headers.AppendHeader("transfer-encoding", "chunked"); | 2508 my_headers.AppendHeader("transfer-encoding", "chunked"); |
2479 SendSynReplyImpl(stream_id, my_headers); | 2509 SendSynReplyImpl(stream_id, my_headers); |
2480 SendDataFrame(stream_id, output->c_str(), output->size(), 0, false); | 2510 SendDataFrame(stream_id, output->c_str(), output->size(), 0, false); |
2481 SendEOFImpl(stream_id); | 2511 SendEOFImpl(stream_id); |
2482 output_ordering_.RemoveStreamId(stream_id); | 2512 output_ordering_.RemoveStreamId(stream_id); |
2483 } | 2513 } |
2484 | 2514 |
2485 size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) { | 2515 size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) { |
2486 SimpleBuffer sb; | 2516 SimpleBuffer sb; |
2487 headers.WriteHeaderAndEndingToBuffer(&sb); | 2517 headers.WriteHeaderAndEndingToBuffer(&sb); |
2488 DataFrame df; | 2518 DataFrame* df = new DataFrame; |
2489 df.size = sb.ReadableBytes(); | 2519 df->size = sb.ReadableBytes(); |
2490 char* buffer = new char[df.size]; | 2520 char* buffer = new char[df->size]; |
2491 df.data = buffer; | 2521 df->data = buffer; |
2492 df.delete_when_done = true; | 2522 df->delete_when_done = true; |
2493 sb.Read(buffer, df.size); | 2523 sb.Read(buffer, df->size); |
2494 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " | 2524 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " |
2495 << stream_id_; | 2525 << stream_id_; |
2496 size_t df_size = df.size; | 2526 size_t df_size = df->size; |
2497 EnqueueDataFrame(df); | 2527 EnqueueDataFrame(df); |
2498 return df_size; | 2528 return df_size; |
2499 } | 2529 } |
2500 | 2530 |
2501 size_t SendSynStreamImpl(uint32 stream_id, const BalsaHeaders& headers) { | 2531 size_t SendSynStreamImpl(uint32 stream_id, const BalsaHeaders& headers) { |
2502 SimpleBuffer sb; | 2532 SimpleBuffer sb; |
2503 headers.WriteHeaderAndEndingToBuffer(&sb); | 2533 headers.WriteHeaderAndEndingToBuffer(&sb); |
2504 DataFrame df; | 2534 DataFrame* df = new DataFrame; |
2505 df.size = sb.ReadableBytes(); | 2535 df->size = sb.ReadableBytes(); |
2506 char* buffer = new char[df.size]; | 2536 char* buffer = new char[df->size]; |
2507 df.data = buffer; | 2537 df->data = buffer; |
2508 df.delete_when_done = true; | 2538 df->delete_when_done = true; |
2509 sb.Read(buffer, df.size); | 2539 sb.Read(buffer, df->size); |
2510 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " | 2540 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header " |
2511 << stream_id_; | 2541 << stream_id_; |
2512 size_t df_size = df.size; | 2542 size_t df_size = df->size; |
2513 EnqueueDataFrame(df); | 2543 EnqueueDataFrame(df); |
2514 return df_size; | 2544 return df_size; |
2515 } | 2545 } |
2516 | 2546 |
2517 void SendDataFrameImpl(uint32 stream_id, const char* data, int64 len, | 2547 void SendDataFrameImpl(uint32 stream_id, const char* data, int64 len, |
2518 uint32 flags, bool compress) { | 2548 uint32 flags, bool compress) { |
2519 char chunk_buf[128]; | 2549 char chunk_buf[128]; |
2520 snprintf(chunk_buf, sizeof(chunk_buf), "%x\r\n", (unsigned int)len); | 2550 snprintf(chunk_buf, sizeof(chunk_buf), "%x\r\n", (unsigned int)len); |
2521 string chunk_description(chunk_buf); | 2551 string chunk_description(chunk_buf); |
2522 DataFrame df; | 2552 DataFrame* df = new DataFrame; |
2523 df.size = chunk_description.size() + len + 2; | 2553 df->size = chunk_description.size() + len + 2; |
2524 char* buffer = new char[df.size]; | 2554 char* buffer = new char[df->size]; |
2525 df.data = buffer; | 2555 df->data = buffer; |
2526 df.delete_when_done = true; | 2556 df->delete_when_done = true; |
2527 memcpy(buffer, chunk_description.data(), chunk_description.size()); | 2557 memcpy(buffer, chunk_description.data(), chunk_description.size()); |
2528 memcpy(buffer + chunk_description.size(), data, len); | 2558 memcpy(buffer + chunk_description.size(), data, len); |
2529 memcpy(buffer + chunk_description.size() + len, "\r\n", 2); | 2559 memcpy(buffer + chunk_description.size() + len, "\r\n", 2); |
2530 EnqueueDataFrame(df); | 2560 EnqueueDataFrame(df); |
2531 } | 2561 } |
2532 | 2562 |
2533 void EnqueueDataFrame(const DataFrame& df) { | 2563 void EnqueueDataFrame(DataFrame* df) { |
2534 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Enqueue data frame: stream " | 2564 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Enqueue data frame: stream " |
2535 << stream_id_; | 2565 << stream_id_; |
2536 connection_->EnqueueDataFrame(df); | 2566 connection_->EnqueueDataFrame(df); |
2537 } | 2567 } |
2538 | 2568 |
2539 void GetOutput() { | 2569 void GetOutput() { |
2540 MemCacheIter* mci = output_ordering_.GetIter(); | 2570 MemCacheIter* mci = output_ordering_.GetIter(); |
2541 if (mci == NULL) { | 2571 if (mci == NULL) { |
2542 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput: nothing to " | 2572 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput: nothing to " |
2543 << "output!?: stream " << stream_id_; | 2573 << "output!?: stream " << stream_id_; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2603 { | 2633 { |
2604 sm_other_interface_ = sm_other_interface; | 2634 sm_other_interface_ = sm_other_interface; |
2605 } | 2635 } |
2606 | 2636 |
2607 void InitSMConnection(SMConnectionPoolInterface* connection_pool, | 2637 void InitSMConnection(SMConnectionPoolInterface* connection_pool, |
2608 SMInterface* sm_interface, | 2638 SMInterface* sm_interface, |
2609 EpollServer* epoll_server, | 2639 EpollServer* epoll_server, |
2610 int fd, | 2640 int fd, |
2611 string server_ip, | 2641 string server_ip, |
2612 string server_port, | 2642 string server_port, |
| 2643 string remote_ip, |
2613 bool use_ssl) | 2644 bool use_ssl) |
2614 { | 2645 { |
2615 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Initializing server " | 2646 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Initializing server " |
2616 << "connection."; | 2647 << "connection."; |
2617 connection_->InitSMConnection(connection_pool, sm_interface, | 2648 connection_->InitSMConnection(connection_pool, sm_interface, |
2618 epoll_server, fd, server_ip, | 2649 epoll_server, fd, server_ip, |
2619 server_port, use_ssl); | 2650 server_port, remote_ip, use_ssl); |
2620 } | 2651 } |
2621 | 2652 |
2622 size_t ProcessReadInput(const char* data, size_t len) { | 2653 size_t ProcessReadInput(const char* data, size_t len) { |
2623 return sm_other_interface_->ProcessWriteInput(data, len); | 2654 return sm_other_interface_->ProcessWriteInput(data, len); |
2624 } | 2655 } |
2625 | 2656 |
2626 size_t ProcessWriteInput(const char* data, size_t len) { | 2657 size_t ProcessWriteInput(const char* data, size_t len) { |
2627 char * dataPtr = new char[len]; | 2658 char * dataPtr = new char[len]; |
2628 memcpy(dataPtr, data, len); | 2659 memcpy(dataPtr, data, len); |
2629 DataFrame df; | 2660 DataFrame* df = new DataFrame; |
2630 df.data = (const char *)dataPtr; | 2661 df->data = (const char *)dataPtr; |
2631 df.size = len; | 2662 df->size = len; |
2632 df.delete_when_done = true; | 2663 df->delete_when_done = true; |
2633 connection_->EnqueueDataFrame(df); | 2664 connection_->EnqueueDataFrame(df); |
2634 return len; | 2665 return len; |
2635 } | 2666 } |
2636 | 2667 |
2637 bool MessageFullyRead() const { | 2668 bool MessageFullyRead() const { |
2638 return false; | 2669 return false; |
2639 } | 2670 } |
2640 | 2671 |
2641 void SetStreamID(uint32 stream_id) {} | 2672 void SetStreamID(uint32 stream_id) {} |
2642 | 2673 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2677 sm_other_interface_ = new StreamerSM(server_connection, this, | 2708 sm_other_interface_ = new StreamerSM(server_connection, this, |
2678 epoll_server_, acceptor_); | 2709 epoll_server_, acceptor_); |
2679 sm_other_interface_->InitSMInterface(this, 0); | 2710 sm_other_interface_->InitSMInterface(this, 0); |
2680 } | 2711 } |
2681 // The Streamer interface is used to stream HTTPS connections, so we | 2712 // The Streamer interface is used to stream HTTPS connections, so we |
2682 // will always use the https_server_ip/port here. | 2713 // will always use the https_server_ip/port here. |
2683 sm_other_interface_->InitSMConnection(NULL, sm_other_interface_, | 2714 sm_other_interface_->InitSMConnection(NULL, sm_other_interface_, |
2684 epoll_server_, -1, | 2715 epoll_server_, -1, |
2685 acceptor_->https_server_ip_, | 2716 acceptor_->https_server_ip_, |
2686 acceptor_->https_server_port_, | 2717 acceptor_->https_server_port_, |
| 2718 "", |
2687 false); | 2719 false); |
2688 | 2720 |
2689 return 1; | 2721 return 1; |
2690 } | 2722 } |
2691 | 2723 |
2692 void NewStream(uint32 stream_id, uint32 priority, const string& filename) { | 2724 void NewStream(uint32 stream_id, uint32 priority, const string& filename) { |
2693 } | 2725 } |
2694 | 2726 |
2695 void AddToOutputOrder(const MemCacheIter& mci) { | 2727 void AddToOutputOrder(const MemCacheIter& mci) { |
2696 } | 2728 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2766 public EpollCallbackInterface, | 2798 public EpollCallbackInterface, |
2767 public SMConnectionPoolInterface { | 2799 public SMConnectionPoolInterface { |
2768 EpollServer epoll_server_; | 2800 EpollServer epoll_server_; |
2769 FlipAcceptor *acceptor_; | 2801 FlipAcceptor *acceptor_; |
2770 SSLState *ssl_state_; | 2802 SSLState *ssl_state_; |
2771 bool use_ssl_; | 2803 bool use_ssl_; |
2772 | 2804 |
2773 vector<SMConnection*> unused_server_connections_; | 2805 vector<SMConnection*> unused_server_connections_; |
2774 vector<SMConnection*> tmp_unused_server_connections_; | 2806 vector<SMConnection*> tmp_unused_server_connections_; |
2775 vector<SMConnection*> allocated_server_connections_; | 2807 vector<SMConnection*> allocated_server_connections_; |
| 2808 list<SMConnection*> active_server_connections_; |
2776 Notification quitting_; | 2809 Notification quitting_; |
2777 MemoryCache* memory_cache_; | 2810 MemoryCache* memory_cache_; |
2778 public: | 2811 public: |
2779 | 2812 |
2780 SMAcceptorThread(FlipAcceptor *acceptor, | 2813 SMAcceptorThread(FlipAcceptor *acceptor, |
2781 MemoryCache* memory_cache) : | 2814 MemoryCache* memory_cache) : |
2782 SimpleThread("SMAcceptorThread"), | 2815 SimpleThread("SMAcceptorThread"), |
2783 acceptor_(acceptor), | 2816 acceptor_(acceptor), |
2784 ssl_state_(NULL), | 2817 ssl_state_(NULL), |
2785 use_ssl_(false), | 2818 use_ssl_(false), |
(...skipping 13 matching lines...) Expand all Loading... |
2799 } | 2832 } |
2800 } | 2833 } |
2801 | 2834 |
2802 ~SMAcceptorThread() { | 2835 ~SMAcceptorThread() { |
2803 for (vector<SMConnection*>::iterator i = | 2836 for (vector<SMConnection*>::iterator i = |
2804 allocated_server_connections_.begin(); | 2837 allocated_server_connections_.begin(); |
2805 i != allocated_server_connections_.end(); | 2838 i != allocated_server_connections_.end(); |
2806 ++i) { | 2839 ++i) { |
2807 delete *i; | 2840 delete *i; |
2808 } | 2841 } |
| 2842 delete ssl_state_; |
2809 } | 2843 } |
2810 | 2844 |
2811 SMConnection* NewConnection() { | 2845 SMConnection* NewConnection() { |
2812 SMConnection* server = | 2846 SMConnection* server = |
2813 SMConnection::NewSMConnection(&epoll_server_, ssl_state_, | 2847 SMConnection::NewSMConnection(&epoll_server_, ssl_state_, |
2814 memory_cache_, acceptor_, | 2848 memory_cache_, acceptor_, |
2815 "client_conn: "); | 2849 "client_conn: "); |
2816 allocated_server_connections_.push_back(server); | 2850 allocated_server_connections_.push_back(server); |
2817 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Making new server."; | 2851 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Making new server."; |
2818 return server; | 2852 return server; |
2819 } | 2853 } |
2820 | 2854 |
2821 SMConnection* FindOrMakeNewSMConnection() { | 2855 SMConnection* FindOrMakeNewSMConnection() { |
2822 if (unused_server_connections_.empty()) { | 2856 if (unused_server_connections_.empty()) { |
2823 return NewConnection(); | 2857 return NewConnection(); |
2824 } | 2858 } |
2825 SMConnection* server = unused_server_connections_.back(); | 2859 SMConnection* server = unused_server_connections_.back(); |
2826 unused_server_connections_.pop_back(); | 2860 unused_server_connections_.pop_back(); |
2827 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Reusing server."; | 2861 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Reusing server."; |
2828 return server; | 2862 return server; |
2829 } | 2863 } |
2830 | 2864 |
2831 void InitWorker() { | 2865 void InitWorker() { |
2832 epoll_server_.RegisterFD(acceptor_->listen_fd_, this, EPOLLIN | EPOLLET); | 2866 epoll_server_.RegisterFD(acceptor_->listen_fd_, this, EPOLLIN | EPOLLET); |
2833 } | 2867 } |
2834 | 2868 |
2835 void HandleConnection(int server_fd) { | 2869 void HandleConnection(int server_fd, struct sockaddr_in *remote_addr) { |
2836 int on = 1; | 2870 int on = 1; |
2837 int rc; | 2871 int rc; |
2838 if (acceptor_->disable_nagle_) { | 2872 if (acceptor_->disable_nagle_) { |
2839 rc = setsockopt(server_fd, IPPROTO_TCP, TCP_NODELAY, | 2873 rc = setsockopt(server_fd, IPPROTO_TCP, TCP_NODELAY, |
2840 reinterpret_cast<char*>(&on), sizeof(on)); | 2874 reinterpret_cast<char*>(&on), sizeof(on)); |
2841 if (rc < 0) { | 2875 if (rc < 0) { |
2842 close(server_fd); | 2876 close(server_fd); |
2843 LOG(ERROR) << "setsockopt() failed fd=" + server_fd; | 2877 LOG(ERROR) << "setsockopt() failed fd=" + server_fd; |
2844 return; | 2878 return; |
2845 } | 2879 } |
2846 } | 2880 } |
2847 | 2881 |
2848 SMConnection* server_connection = FindOrMakeNewSMConnection(); | 2882 SMConnection* server_connection = FindOrMakeNewSMConnection(); |
2849 if (server_connection == NULL) { | 2883 if (server_connection == NULL) { |
2850 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Closing fd " << server_fd; | 2884 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: Closing fd " << server_fd; |
2851 close(server_fd); | 2885 close(server_fd); |
2852 return; | 2886 return; |
2853 } | 2887 } |
| 2888 string remote_ip = inet_ntoa(remote_addr->sin_addr); |
2854 server_connection->InitSMConnection(this, | 2889 server_connection->InitSMConnection(this, |
2855 NULL, | 2890 NULL, |
2856 &epoll_server_, | 2891 &epoll_server_, |
2857 server_fd, | 2892 server_fd, |
2858 "", "", | 2893 "", "", remote_ip, |
2859 use_ssl_); | 2894 use_ssl_); |
| 2895 if (server_connection->initialized()) |
| 2896 active_server_connections_.push_back(server_connection); |
2860 } | 2897 } |
2861 | 2898 |
2862 void AcceptFromListenFD() { | 2899 void AcceptFromListenFD() { |
2863 if (acceptor_->accepts_per_wake_ > 0) { | 2900 if (acceptor_->accepts_per_wake_ > 0) { |
2864 for (int i = 0; i < acceptor_->accepts_per_wake_; ++i) { | 2901 for (int i = 0; i < acceptor_->accepts_per_wake_; ++i) { |
2865 struct sockaddr address; | 2902 struct sockaddr address; |
2866 socklen_t socklen = sizeof(address); | 2903 socklen_t socklen = sizeof(address); |
2867 int fd = accept(acceptor_->listen_fd_, &address, &socklen); | 2904 int fd = accept(acceptor_->listen_fd_, &address, &socklen); |
2868 if (fd == -1) { | 2905 if (fd == -1) { |
2869 if (errno != 11) { | 2906 if (errno != 11) { |
2870 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: accept fail(" | 2907 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: accept fail(" |
2871 << acceptor_->listen_fd_ << "): " << errno << ": " | 2908 << acceptor_->listen_fd_ << "): " << errno << ": " |
2872 << strerror(errno); | 2909 << strerror(errno); |
2873 } | 2910 } |
2874 break; | 2911 break; |
2875 } | 2912 } |
2876 VLOG(1) << ACCEPTOR_CLIENT_IDENT << " Accepted connection"; | 2913 VLOG(1) << ACCEPTOR_CLIENT_IDENT << " Accepted connection"; |
2877 HandleConnection(fd); | 2914 HandleConnection(fd, (struct sockaddr_in *)&address); |
2878 } | 2915 } |
2879 } else { | 2916 } else { |
2880 while (true) { | 2917 while (true) { |
2881 struct sockaddr address; | 2918 struct sockaddr address; |
2882 socklen_t socklen = sizeof(address); | 2919 socklen_t socklen = sizeof(address); |
2883 int fd = accept(acceptor_->listen_fd_, &address, &socklen); | 2920 int fd = accept(acceptor_->listen_fd_, &address, &socklen); |
2884 if (fd == -1) { | 2921 if (fd == -1) { |
2885 if (errno != 11) { | 2922 if (errno != 11) { |
2886 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: accept fail(" | 2923 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Acceptor: accept fail(" |
2887 << acceptor_->listen_fd_ << "): " << errno << ": " | 2924 << acceptor_->listen_fd_ << "): " << errno << ": " |
2888 << strerror(errno); | 2925 << strerror(errno); |
2889 } | 2926 } |
2890 break; | 2927 break; |
2891 } | 2928 } |
2892 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Accepted connection"; | 2929 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Accepted connection"; |
2893 HandleConnection(fd); | 2930 HandleConnection(fd, (struct sockaddr_in *)&address); |
2894 } | 2931 } |
2895 } | 2932 } |
2896 } | 2933 } |
2897 | 2934 |
2898 // EpollCallbackInteface virtual functions. | 2935 // EpollCallbackInteface virtual functions. |
2899 virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) { } | 2936 virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) { } |
2900 virtual void OnModification(int fd, int event_mask) { } | 2937 virtual void OnModification(int fd, int event_mask) { } |
2901 virtual void OnEvent(int fd, EpollEvent* event) { | 2938 virtual void OnEvent(int fd, EpollEvent* event) { |
2902 if (event->in_events | EPOLLIN) { | 2939 if (event->in_events | EPOLLIN) { |
2903 VLOG(2) << ACCEPTOR_CLIENT_IDENT | 2940 VLOG(2) << ACCEPTOR_CLIENT_IDENT |
2904 << "Acceptor: Accepting based upon epoll events"; | 2941 << "Acceptor: Accepting based upon epoll events"; |
2905 AcceptFromListenFD(); | 2942 AcceptFromListenFD(); |
2906 } | 2943 } |
2907 } | 2944 } |
2908 virtual void OnUnregistration(int fd, bool replaced) { } | 2945 virtual void OnUnregistration(int fd, bool replaced) { } |
2909 virtual void OnShutdown(EpollServer* eps, int fd) { } | 2946 virtual void OnShutdown(EpollServer* eps, int fd) { } |
2910 | 2947 |
2911 void Quit() { | 2948 void Quit() { |
2912 quitting_.Notify(); | 2949 quitting_.Notify(); |
2913 } | 2950 } |
2914 | 2951 |
| 2952 // Iterates through a list of active connections expiring any that have been |
| 2953 // idle longer than the configured timeout. |
| 2954 void HandleConnectionIdleTimeout() { |
| 2955 int cur_time = time(NULL); |
| 2956 static time_t oldest_time = cur_time; |
| 2957 // Only iterate the list if we speculate that a connection is ready to be |
| 2958 // expired |
| 2959 if ((cur_time - oldest_time) < g_proxy_config.idle_timeout_s_) |
| 2960 return; |
| 2961 list<SMConnection*>::iterator iter = active_server_connections_.begin(); |
| 2962 while (iter != active_server_connections_.end()) { |
| 2963 SMConnection *conn = *iter; |
| 2964 int elapsed_time = (cur_time - conn->last_read_time_); |
| 2965 if (elapsed_time > g_proxy_config.idle_timeout_s_) { |
| 2966 conn->Cleanup("Connection idle timeout reached."); |
| 2967 iter = active_server_connections_.erase(iter); |
| 2968 continue; |
| 2969 } |
| 2970 if (conn->last_read_time_ < oldest_time) |
| 2971 oldest_time = conn->last_read_time_; |
| 2972 iter++; |
| 2973 } |
| 2974 if ((cur_time - oldest_time) >= g_proxy_config.idle_timeout_s_) |
| 2975 oldest_time = cur_time; |
| 2976 } |
| 2977 |
2915 void Run() { | 2978 void Run() { |
2916 while (!quitting_.HasBeenNotified()) { | 2979 while (!quitting_.HasBeenNotified()) { |
2917 epoll_server_.set_timeout_in_us(10 * 1000); // 10 ms | 2980 epoll_server_.set_timeout_in_us(10 * 1000); // 10 ms |
2918 epoll_server_.WaitForEventsAndExecuteCallbacks(); | 2981 epoll_server_.WaitForEventsAndExecuteCallbacks(); |
2919 unused_server_connections_.insert(unused_server_connections_.end(), | 2982 unused_server_connections_.insert(unused_server_connections_.end(), |
2920 tmp_unused_server_connections_.begin(), | 2983 tmp_unused_server_connections_.begin(), |
2921 tmp_unused_server_connections_.end()); | 2984 tmp_unused_server_connections_.end()); |
2922 tmp_unused_server_connections_.clear(); | 2985 tmp_unused_server_connections_.clear(); |
| 2986 HandleConnectionIdleTimeout(); |
2923 } | 2987 } |
2924 } | 2988 } |
2925 | 2989 |
2926 // SMConnections will use this: | 2990 // SMConnections will use this: |
2927 virtual void SMConnectionDone(SMConnection* sc) { | 2991 virtual void SMConnectionDone(SMConnection* sc) { |
2928 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Done with connection."; | 2992 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Done with connection."; |
2929 tmp_unused_server_connections_.push_back(sc); | 2993 tmp_unused_server_connections_.push_back(sc); |
2930 } | 2994 } |
2931 }; | 2995 }; |
2932 | 2996 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2993 } | 3057 } |
2994 | 3058 |
2995 const char* BoolToStr(bool b) { | 3059 const char* BoolToStr(bool b) { |
2996 if (b) | 3060 if (b) |
2997 return "true"; | 3061 return "true"; |
2998 return "false"; | 3062 return "false"; |
2999 } | 3063 } |
3000 | 3064 |
3001 //////////////////////////////////////////////////////////////////////////////// | 3065 //////////////////////////////////////////////////////////////////////////////// |
3002 | 3066 |
| 3067 static bool wantExit = false; |
| 3068 static bool wantLogClose = false; |
| 3069 void SignalHandler(int signum) |
| 3070 { |
| 3071 switch(signum) { |
| 3072 case SIGTERM: |
| 3073 case SIGINT: |
| 3074 wantExit = true; |
| 3075 break; |
| 3076 case SIGHUP: |
| 3077 wantLogClose = true; |
| 3078 break; |
| 3079 } |
| 3080 } |
| 3081 |
| 3082 static int OpenPidFile(const char *pidfile) |
| 3083 { |
| 3084 int fd; |
| 3085 struct stat pid_stat; |
| 3086 int ret; |
| 3087 |
| 3088 fd = open(pidfile, O_RDWR | O_CREAT, 0600); |
| 3089 if (fd == -1) { |
| 3090 cerr << "Could not open pid file '" << pidfile << "' for reading.\n"; |
| 3091 exit(1); |
| 3092 } |
| 3093 |
| 3094 ret = flock(fd, LOCK_EX | LOCK_NB); |
| 3095 if (ret == -1) { |
| 3096 if (errno == EWOULDBLOCK) { |
| 3097 cerr << "Flip server is already running.\n"; |
| 3098 } else { |
| 3099 cerr << "Error getting lock on pid file: " << strerror(errno) << "\n"; |
| 3100 } |
| 3101 exit(1); |
| 3102 } |
| 3103 |
| 3104 if (fstat(fd, &pid_stat) == -1) { |
| 3105 cerr << "Could not stat pid file '" << pidfile << "': " << strerror(errno) |
| 3106 << "\n"; |
| 3107 } |
| 3108 if (pid_stat.st_size != 0) { |
| 3109 if (ftruncate(fd, pid_stat.st_size) == -1) { |
| 3110 cerr << "Could not truncate pid file '" << pidfile << "': " |
| 3111 << strerror(errno) << "\n"; |
| 3112 } |
| 3113 } |
| 3114 |
| 3115 char pid_str[8]; |
| 3116 snprintf(pid_str, sizeof(pid_str), "%d", getpid()); |
| 3117 int bytes = static_cast<int>(strlen(pid_str)); |
| 3118 if (write(fd, pid_str, strlen(pid_str)) != bytes) { |
| 3119 cerr << "Could not write pid file: " << strerror(errno) << "\n"; |
| 3120 close(fd); |
| 3121 exit(1); |
| 3122 } |
| 3123 |
| 3124 return fd; |
| 3125 } |
| 3126 |
3003 int main (int argc, char**argv) | 3127 int main (int argc, char**argv) |
3004 { | 3128 { |
3005 unsigned int i = 0; | 3129 unsigned int i = 0; |
3006 bool wait_for_iface = false; | 3130 bool wait_for_iface = false; |
| 3131 int pidfile_fd; |
3007 | 3132 |
3008 signal(SIGPIPE, SIG_IGN); | 3133 signal(SIGPIPE, SIG_IGN); |
| 3134 signal(SIGTERM, SignalHandler); |
| 3135 signal(SIGINT, SignalHandler); |
| 3136 signal(SIGHUP, SignalHandler); |
3009 | 3137 |
3010 CommandLine::Init(argc, argv); | 3138 CommandLine::Init(argc, argv); |
3011 CommandLine cl(argc, argv); | 3139 CommandLine cl(argc, argv); |
3012 | 3140 |
3013 if (cl.HasSwitch("help") || argc < 2) { | 3141 if (cl.HasSwitch("help") || argc < 2) { |
3014 cout << argv[0] << " <options>\n"; | 3142 cout << argv[0] << " <options>\n"; |
3015 cout << " Proxy options:\n"; | 3143 cout << " Proxy options:\n"; |
3016 cout << "\t--proxy<1..n>=\"<listen ip>,<listen port>," | 3144 cout << "\t--proxy<1..n>=\"<listen ip>,<listen port>," |
3017 << "<ssl cert filename>,\n" | 3145 << "<ssl cert filename>,\n" |
3018 << "\t <ssl key filename>,<http server ip>," | 3146 << "\t <ssl key filename>,<http server ip>," |
3019 << "<http server port>,\n" | 3147 << "<http server port>,\n" |
3020 << "\t [https server ip],[https server port]," | 3148 << "\t [https server ip],[https server port]," |
3021 << "<spdy only 0|1>\"\n"; | 3149 << "<spdy only 0|1>\"\n"; |
3022 cout << "\t * The https server ip and port may be left empty if they are" | 3150 cout << "\t * The https server ip and port may be left empty if they are" |
3023 << " the same as\n" | 3151 << " the same as\n" |
3024 << "\t the http server fields.\n"; | 3152 << "\t the http server fields.\n"; |
3025 cout << "\t * spdy only prevents non-spdy https connections from being" | 3153 cout << "\t * spdy only prevents non-spdy https connections from being" |
3026 << " passed\n" | 3154 << " passed\n" |
3027 << "\t through the proxy listen ip:port.\n"; | 3155 << "\t through the proxy listen ip:port.\n"; |
3028 cout << "\t--forward-ip-header=<header name>\n"; | 3156 cout << "\t--forward-ip-header=<header name>\n"; |
3029 cout << "\n Server options:\n"; | 3157 cout << "\n Server options:\n"; |
3030 cout << "\t--spdy-server=\"<listen ip>,<listen port>,[ssl cert filename],\n" | 3158 cout << "\t--spdy-server=\"<listen ip>,<listen port>,[ssl cert filename]," |
3031 << "\t [ssl key filename]\"\n"; | 3159 << "\n\t [ssl key filename]\"\n"; |
3032 cout << "\t--http-server=\"<listen ip>,<listen port>,[ssl cert filename],\n" | 3160 cout << "\t--http-server=\"<listen ip>,<listen port>,[ssl cert filename]," |
3033 << "\t [ssl key filename]\"\n"; | 3161 << "\n\t [ssl key filename]\"\n"; |
3034 cout << "\t * Leaving the ssl cert and key fields empty will disable ssl" | 3162 cout << "\t * Leaving the ssl cert and key fields empty will disable ssl" |
3035 << " for the\n" | 3163 << " for the\n" |
3036 << "\t http and spdy flip servers\n"; | 3164 << "\t http and spdy flip servers\n"; |
3037 cout << "\n Global options:\n"; | 3165 cout << "\n Global options:\n"; |
3038 cout << "\t--logdest=<file|system|both>\n"; | 3166 cout << "\t--logdest=<file|system|both>\n"; |
3039 cout << "\t--logfile=<logfile>\n"; | 3167 cout << "\t--logfile=<logfile>\n"; |
3040 cout << "\t--wait-for-iface\n"; | 3168 cout << "\t--wait-for-iface\n"; |
3041 cout << "\t * The flip server will block until the listen ip has been" | 3169 cout << "\t * The flip server will block until the listen ip has been" |
3042 << " raised.\n"; | 3170 << " raised.\n"; |
3043 cout << "\t--ssl-session-expiry=<seconds> (default is 300)\n"; | 3171 cout << "\t--ssl-session-expiry=<seconds> (default is 300)\n"; |
3044 cout << "\t--ssl-disable-compression\n"; | 3172 cout << "\t--ssl-disable-compression\n"; |
| 3173 cout << "\t--idle-timeout=<seconds> (default is 300)\n"; |
| 3174 cout << "\t--pidfile=<filepath> (default /var/run/flip-server.pid)\n"; |
3045 cout << "\t--help\n"; | 3175 cout << "\t--help\n"; |
3046 exit(0); | 3176 exit(0); |
3047 } | 3177 } |
3048 | 3178 |
| 3179 if (cl.HasSwitch("pidfile")) { |
| 3180 pidfile_fd = OpenPidFile(cl.GetSwitchValueASCII("pidfile").c_str()); |
| 3181 } else { |
| 3182 pidfile_fd = OpenPidFile(PIDFILE); |
| 3183 } |
| 3184 |
3049 g_proxy_config.server_think_time_in_s_ = FLAGS_server_think_time_in_s; | 3185 g_proxy_config.server_think_time_in_s_ = FLAGS_server_think_time_in_s; |
3050 | 3186 |
3051 if (cl.HasSwitch("forward-ip-header")) { | 3187 if (cl.HasSwitch("forward-ip-header")) { |
3052 g_proxy_config.forward_ip_header_enabled_ = true; | 3188 g_proxy_config.forward_ip_header_enabled_ = true; |
3053 g_proxy_config.forward_ip_header_ = | 3189 g_proxy_config.forward_ip_header_ = |
3054 cl.GetSwitchValueASCII("forward-ip-header"); | 3190 cl.GetSwitchValueASCII("forward-ip-header"); |
3055 } else { | 3191 } else { |
3056 g_proxy_config.forward_ip_header_enabled_ = false; | 3192 g_proxy_config.forward_ip_header_enabled_ = false; |
3057 } | 3193 } |
3058 | 3194 |
(...skipping 23 matching lines...) Expand all Loading... |
3082 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { | 3218 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { |
3083 LOG(FATAL) << "Logging destination requires a log file to be specified."; | 3219 LOG(FATAL) << "Logging destination requires a log file to be specified."; |
3084 } | 3220 } |
3085 | 3221 |
3086 if (cl.HasSwitch("wait-for-iface")) { | 3222 if (cl.HasSwitch("wait-for-iface")) { |
3087 wait_for_iface = true; | 3223 wait_for_iface = true; |
3088 } | 3224 } |
3089 | 3225 |
3090 if (cl.HasSwitch("ssl-session-expiry")) { | 3226 if (cl.HasSwitch("ssl-session-expiry")) { |
3091 string session_expiry = cl.GetSwitchValueASCII("ssl-session-expiry"); | 3227 string session_expiry = cl.GetSwitchValueASCII("ssl-session-expiry"); |
3092 g_proxy_config.ssl_session_expiry_ = atoi( session_expiry.c_str() ); | 3228 g_proxy_config.ssl_session_expiry_ = atoi(session_expiry.c_str()); |
3093 } | 3229 } |
3094 | 3230 |
3095 if (cl.HasSwitch("ssl-disable-compression")) { | 3231 if (cl.HasSwitch("ssl-disable-compression")) { |
3096 g_proxy_config.ssl_disable_compression_ = true; | 3232 g_proxy_config.ssl_disable_compression_ = true; |
3097 } | 3233 } |
3098 | 3234 |
| 3235 if (cl.HasSwitch("idle-timeout")) { |
| 3236 g_proxy_config.idle_timeout_s_ = |
| 3237 atoi(cl.GetSwitchValueASCII("idle-timeout").c_str()); |
| 3238 } |
| 3239 |
3099 if (cl.HasSwitch("force_spdy")) | 3240 if (cl.HasSwitch("force_spdy")) |
3100 FLAGS_force_spdy = true; | 3241 FLAGS_force_spdy = true; |
3101 | 3242 |
3102 InitLogging(g_proxy_config.log_filename_.c_str(), | 3243 InitLogging(g_proxy_config.log_filename_.c_str(), |
3103 g_proxy_config.log_destination_, | 3244 g_proxy_config.log_destination_, |
3104 logging::DONT_LOCK_LOG_FILE, | 3245 logging::DONT_LOCK_LOG_FILE, |
3105 logging::APPEND_TO_OLD_LOG_FILE, | 3246 logging::APPEND_TO_OLD_LOG_FILE, |
3106 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); | 3247 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); |
3107 | 3248 |
3108 LOG(INFO) << "Flip SPDY proxy started with configuration:"; | 3249 LOG(INFO) << "Flip SPDY proxy started with configuration:"; |
3109 LOG(INFO) << "Logging destination : " << g_proxy_config.log_destination_; | 3250 LOG(INFO) << "Logging destination : " << g_proxy_config.log_destination_; |
3110 LOG(INFO) << "Log file : " << g_proxy_config.log_filename_; | 3251 LOG(INFO) << "Log file : " << g_proxy_config.log_filename_; |
3111 LOG(INFO) << "Forward IP Header : " | 3252 LOG(INFO) << "Forward IP Header : " |
3112 << (g_proxy_config.forward_ip_header_enabled_ ? | 3253 << (g_proxy_config.forward_ip_header_enabled_ ? |
3113 g_proxy_config.forward_ip_header_ : "(disabled)"); | 3254 g_proxy_config.forward_ip_header_ : "(disabled)"); |
3114 LOG(INFO) << "Wait for interfaces : " << (wait_for_iface?"true":"false"); | 3255 LOG(INFO) << "Wait for interfaces : " << (wait_for_iface?"true":"false"); |
3115 LOG(INFO) << "Accept backlog size : " << FLAGS_accept_backlog_size; | 3256 LOG(INFO) << "Accept backlog size : " << FLAGS_accept_backlog_size; |
3116 LOG(INFO) << "Accepts per wake : " << FLAGS_accepts_per_wake; | 3257 LOG(INFO) << "Accepts per wake : " << FLAGS_accepts_per_wake; |
3117 LOG(INFO) << "Disable nagle : " | 3258 LOG(INFO) << "Disable nagle : " |
3118 << (FLAGS_disable_nagle?"true":"false"); | 3259 << (FLAGS_disable_nagle?"true":"false"); |
3119 LOG(INFO) << "Reuseport : " << (FLAGS_reuseport?"true":"false"); | 3260 LOG(INFO) << "Reuseport : " |
| 3261 << (FLAGS_reuseport?"true":"false"); |
3120 LOG(INFO) << "Force SPDY : " | 3262 LOG(INFO) << "Force SPDY : " |
3121 << (FLAGS_force_spdy?"true":"false"); | 3263 << (FLAGS_force_spdy?"true":"false"); |
3122 LOG(INFO) << "SSL session expiry : " | 3264 LOG(INFO) << "SSL session expiry : " |
3123 << g_proxy_config.ssl_session_expiry_; | 3265 << g_proxy_config.ssl_session_expiry_; |
3124 LOG(INFO) << "SSL disable compression : " | 3266 LOG(INFO) << "SSL disable compression : " |
3125 << g_proxy_config.ssl_disable_compression_; | 3267 << g_proxy_config.ssl_disable_compression_; |
| 3268 LOG(INFO) << "Connection idle timeout : " << g_proxy_config.idle_timeout_s_; |
3126 | 3269 |
3127 // Proxy Acceptors | 3270 // Proxy Acceptors |
3128 while (true) { | 3271 while (true) { |
3129 i += 1; | 3272 i += 1; |
3130 std::stringstream name; | 3273 std::stringstream name; |
3131 name << "proxy" << i; | 3274 name << "proxy" << i; |
3132 if (!cl.HasSwitch(name.str())) { | 3275 if (!cl.HasSwitch(name.str())) { |
3133 break; | 3276 break; |
3134 } | 3277 } |
3135 string value = cl.GetSwitchValueASCII(name.str()); | 3278 string value = cl.GetSwitchValueASCII(name.str()); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3202 // we either must make the MemoryCache threadsafe, or use | 3345 // we either must make the MemoryCache threadsafe, or use |
3203 // a separate MemoryCache for each thread. | 3346 // a separate MemoryCache for each thread. |
3204 // | 3347 // |
3205 // The latter is what is currently being done as we spawn | 3348 // The latter is what is currently being done as we spawn |
3206 // a separate thread for each http and spdy server acceptor. | 3349 // a separate thread for each http and spdy server acceptor. |
3207 | 3350 |
3208 sm_worker_threads_.back()->InitWorker(); | 3351 sm_worker_threads_.back()->InitWorker(); |
3209 sm_worker_threads_.back()->Start(); | 3352 sm_worker_threads_.back()->Start(); |
3210 } | 3353 } |
3211 | 3354 |
3212 while (true) { | 3355 while (!wantExit) { |
| 3356 // Close logfile when HUP signal is received. Logging system will |
| 3357 // automatically reopen on next log message. |
| 3358 if ( wantLogClose ) { |
| 3359 wantLogClose = false; |
| 3360 VLOG(1) << "HUP received, reopening log file."; |
| 3361 logging::CloseLogFile(); |
| 3362 } |
3213 if (GotQuitFromStdin()) { | 3363 if (GotQuitFromStdin()) { |
3214 for (unsigned int i = 0; i < sm_worker_threads_.size(); ++i) { | 3364 for (unsigned int i = 0; i < sm_worker_threads_.size(); ++i) { |
3215 sm_worker_threads_[i]->Quit(); | 3365 sm_worker_threads_[i]->Quit(); |
3216 } | 3366 } |
3217 for (unsigned int i = 0; i < sm_worker_threads_.size(); ++i) { | 3367 for (unsigned int i = 0; i < sm_worker_threads_.size(); ++i) { |
3218 sm_worker_threads_[i]->Join(); | 3368 sm_worker_threads_[i]->Join(); |
3219 } | 3369 } |
3220 return 0; | 3370 break; |
3221 } | 3371 } |
3222 usleep(1000*10); // 10 ms | 3372 usleep(1000*10); // 10 ms |
3223 } | 3373 } |
3224 | 3374 |
| 3375 unlink(PIDFILE); |
| 3376 close(pidfile_fd); |
3225 return 0; | 3377 return 0; |
3226 } | 3378 } |
OLD | NEW |