Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 11366155: SSLClientSocket::IsConnected should care for internal buffers (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: one more pitfall Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/data/websocket/split_packet_check.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6 // from AuthCertificateCallback() in 6 // from AuthCertificateCallback() in
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8 8
9 /* ***** BEGIN LICENSE BLOCK ***** 9 /* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 // any time. 635 // any time.
636 const HandshakeState& state() const { return network_handshake_state_; } 636 const HandshakeState& state() const { return network_handshake_state_; }
637 637
638 // Called on the network task runner. 638 // Called on the network task runner.
639 // Read() and Write() mirror the net::Socket functions of the same name. 639 // Read() and Write() mirror the net::Socket functions of the same name.
640 // If ERR_IO_PENDING is returned, |callback| will be invoked on the network 640 // If ERR_IO_PENDING is returned, |callback| will be invoked on the network
641 // task runner at a later point, unless the caller calls Detach(). 641 // task runner at a later point, unless the caller calls Detach().
642 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback); 642 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
643 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback); 643 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
644 644
645 // Called on the network task runner.
646 bool IsConnected();
647 bool HasPendingAsyncOperation();
648 bool HasUnhandledReceivedData();
649
645 private: 650 private:
646 friend class base::RefCountedThreadSafe<Core>; 651 friend class base::RefCountedThreadSafe<Core>;
647 ~Core(); 652 ~Core();
648 653
649 enum State { 654 enum State {
650 STATE_NONE, 655 STATE_NONE,
651 STATE_HANDSHAKE, 656 STATE_HANDSHAKE,
652 STATE_GET_DOMAIN_BOUND_CERT_COMPLETE, 657 STATE_GET_DOMAIN_BOUND_CERT_COMPLETE,
653 }; 658 };
654 659
660 enum Operation {
661 OPERATION_READ,
662 OPERATION_WRITE,
663 OPERATION_UPDATE,
664 };
665
655 bool OnNSSTaskRunner() const; 666 bool OnNSSTaskRunner() const;
656 bool OnNetworkTaskRunner() const; 667 bool OnNetworkTaskRunner() const;
657 668
658 //////////////////////////////////////////////////////////////////////////// 669 ////////////////////////////////////////////////////////////////////////////
659 // Methods that are ONLY called on the NSS task runner: 670 // Methods that are ONLY called on the NSS task runner:
660 //////////////////////////////////////////////////////////////////////////// 671 ////////////////////////////////////////////////////////////////////////////
661 672
662 // Called by NSS during full handshakes to allow the application to 673 // Called by NSS during full handshakes to allow the application to
663 // verify the certificate. Instead of verifying the certificate in the midst 674 // verify the certificate. Instead of verifying the certificate in the midst
664 // of the handshake, SECSuccess is always returned and the peer's certificate 675 // of the handshake, SECSuccess is always returned and the peer's certificate
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 //////////////////////////////////////////////////////////////////////////// 778 ////////////////////////////////////////////////////////////////////////////
768 // Methods that are ONLY called on the network task runner: 779 // Methods that are ONLY called on the network task runner:
769 //////////////////////////////////////////////////////////////////////////// 780 ////////////////////////////////////////////////////////////////////////////
770 int DoBufferRecv(IOBuffer* buffer, int len); 781 int DoBufferRecv(IOBuffer* buffer, int len);
771 int DoBufferSend(IOBuffer* buffer, int len); 782 int DoBufferSend(IOBuffer* buffer, int len);
772 int DoGetDomainBoundCert(const std::string& origin, 783 int DoGetDomainBoundCert(const std::string& origin,
773 const std::vector<uint8>& requested_cert_types); 784 const std::vector<uint8>& requested_cert_types);
774 785
775 void OnGetDomainBoundCertComplete(int result); 786 void OnGetDomainBoundCertComplete(int result);
776 void OnHandshakeStateUpdated(const HandshakeState& state); 787 void OnHandshakeStateUpdated(const HandshakeState& state);
788 void OnNSSTaskRunnerStateUpdated(int amount_in_read_buffer,
Ryan Sleevi 2013/01/23 01:46:20 Naming: "OnNSSTaskRunnerStateUpdated" is perhaps a
Takashi Toyoshima 2013/01/23 06:53:02 Agreed. Done!
789 bool closed,
790 Operation operation,
791 const base::Closure& callback);
792 void DidNSSRead(int result);
793 void DidNSSWrite(int result);
777 794
778 //////////////////////////////////////////////////////////////////////////// 795 ////////////////////////////////////////////////////////////////////////////
779 // Methods that are called on both the network task runner and the NSS 796 // Methods that are called on both the network task runner and the NSS
780 // task runner. 797 // task runner.
781 //////////////////////////////////////////////////////////////////////////// 798 ////////////////////////////////////////////////////////////////////////////
782 void OnHandshakeIOComplete(int result); 799 void OnHandshakeIOComplete(int result);
783 void BufferRecvComplete(IOBuffer* buffer, int result); 800 void BufferRecvComplete(IOBuffer* buffer, int result);
784 void BufferSendComplete(int result); 801 void BufferSendComplete(int result);
785 802
786 // PostOrRunCallback is a helper function to ensure that |callback| is 803 // PostOrRunCallback is a helper function to ensure that |callback| is
(...skipping 23 matching lines...) Expand all
810 ClientSocketHandle* transport_; 827 ClientSocketHandle* transport_;
811 base::WeakPtrFactory<BoundNetLog> weak_net_log_factory_; 828 base::WeakPtrFactory<BoundNetLog> weak_net_log_factory_;
812 829
813 // The current handshake state. Mirrors |nss_handshake_state_|. 830 // The current handshake state. Mirrors |nss_handshake_state_|.
814 HandshakeState network_handshake_state_; 831 HandshakeState network_handshake_state_;
815 832
816 // The service for retrieving Channel ID keys. May be NULL. 833 // The service for retrieving Channel ID keys. May be NULL.
817 ServerBoundCertService* server_bound_cert_service_; 834 ServerBoundCertService* server_bound_cert_service_;
818 ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_; 835 ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_;
819 836
837 // The information about NSS task runner.
838 int unhandled_buffer_size_;
839 bool nss_waiting_read_;
840 bool nss_waiting_write_;
841 bool nss_is_closed_;
842
820 //////////////////////////////////////////////////////////////////////////// 843 ////////////////////////////////////////////////////////////////////////////
821 // Members that are ONLY accessed on the NSS task runner: 844 // Members that are ONLY accessed on the NSS task runner:
822 //////////////////////////////////////////////////////////////////////////// 845 ////////////////////////////////////////////////////////////////////////////
823 HostPortPair host_and_port_; 846 HostPortPair host_and_port_;
824 SSLConfig ssl_config_; 847 SSLConfig ssl_config_;
825 848
826 // NSS SSL socket. 849 // NSS SSL socket.
827 PRFileDesc* nss_fd_; 850 PRFileDesc* nss_fd_;
828 851
829 // Buffers for the network end of the SSL state machine 852 // Buffers for the network end of the SSL state machine
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 base::SequencedTaskRunner* nss_task_runner, 912 base::SequencedTaskRunner* nss_task_runner,
890 ClientSocketHandle* transport, 913 ClientSocketHandle* transport,
891 const HostPortPair& host_and_port, 914 const HostPortPair& host_and_port,
892 const SSLConfig& ssl_config, 915 const SSLConfig& ssl_config,
893 BoundNetLog* net_log, 916 BoundNetLog* net_log,
894 ServerBoundCertService* server_bound_cert_service) 917 ServerBoundCertService* server_bound_cert_service)
895 : detached_(false), 918 : detached_(false),
896 transport_(transport), 919 transport_(transport),
897 weak_net_log_factory_(net_log), 920 weak_net_log_factory_(net_log),
898 server_bound_cert_service_(server_bound_cert_service), 921 server_bound_cert_service_(server_bound_cert_service),
922 unhandled_buffer_size_(0),
923 nss_waiting_read_(false),
924 nss_waiting_write_(false),
925 nss_is_closed_(false),
899 host_and_port_(host_and_port), 926 host_and_port_(host_and_port),
900 ssl_config_(ssl_config), 927 ssl_config_(ssl_config),
901 nss_fd_(NULL), 928 nss_fd_(NULL),
902 nss_bufs_(NULL), 929 nss_bufs_(NULL),
903 next_handshake_state_(STATE_NONE), 930 next_handshake_state_(STATE_NONE),
904 channel_id_xtn_negotiated_(false), 931 channel_id_xtn_negotiated_(false),
905 channel_id_needed_(false), 932 channel_id_needed_(false),
906 client_auth_cert_needed_(false), 933 client_auth_cert_needed_(false),
907 handshake_callback_called_(false), 934 handshake_callback_called_(false),
908 transport_recv_busy_(false), 935 transport_recv_busy_(false),
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 1109
1083 domain_bound_cert_request_handle_.Cancel(); 1110 domain_bound_cert_request_handle_.Cancel();
1084 } 1111 }
1085 1112
1086 int SSLClientSocketNSS::Core::Read(IOBuffer* buf, int buf_len, 1113 int SSLClientSocketNSS::Core::Read(IOBuffer* buf, int buf_len,
1087 const CompletionCallback& callback) { 1114 const CompletionCallback& callback) {
1088 if (!OnNSSTaskRunner()) { 1115 if (!OnNSSTaskRunner()) {
1089 DCHECK(OnNetworkTaskRunner()); 1116 DCHECK(OnNetworkTaskRunner());
1090 DCHECK(!detached_); 1117 DCHECK(!detached_);
1091 DCHECK(transport_); 1118 DCHECK(transport_);
1119 DCHECK(!nss_waiting_read_);
1092 1120
1121 nss_waiting_read_ = true;
1093 bool posted = nss_task_runner_->PostTask( 1122 bool posted = nss_task_runner_->PostTask(
1094 FROM_HERE, 1123 FROM_HERE,
1095 base::Bind(IgnoreResult(&Core::Read), this, make_scoped_refptr(buf), 1124 base::Bind(IgnoreResult(&Core::Read), this, make_scoped_refptr(buf),
1096 buf_len, callback)); 1125 buf_len, callback));
1126 if (!posted) {
1127 nss_is_closed_ = true;
1128 nss_waiting_read_ = false;
1129 }
1097 return posted ? ERR_IO_PENDING : ERR_ABORTED; 1130 return posted ? ERR_IO_PENDING : ERR_ABORTED;
1098 } 1131 }
1099 1132
1100 DCHECK(OnNSSTaskRunner()); 1133 DCHECK(OnNSSTaskRunner());
1101 DCHECK(handshake_callback_called_); 1134 DCHECK(handshake_callback_called_);
1102 DCHECK_EQ(STATE_NONE, next_handshake_state_); 1135 DCHECK_EQ(STATE_NONE, next_handshake_state_);
1103 DCHECK(user_read_callback_.is_null()); 1136 DCHECK(user_read_callback_.is_null());
1104 DCHECK(user_connect_callback_.is_null()); 1137 DCHECK(user_connect_callback_.is_null());
1105 DCHECK(!user_read_buf_); 1138 DCHECK(!user_read_buf_);
1106 DCHECK(nss_bufs_); 1139 DCHECK(nss_bufs_);
1107 1140
1108 user_read_buf_ = buf; 1141 user_read_buf_ = buf;
1109 user_read_buf_len_ = buf_len; 1142 user_read_buf_len_ = buf_len;
1110 1143
1111 int rv = DoReadLoop(OK); 1144 int rv = DoReadLoop(OK);
1112 if (rv == ERR_IO_PENDING) { 1145 if (rv == ERR_IO_PENDING) {
1146 if (OnNetworkTaskRunner())
1147 nss_waiting_read_ = true;
1113 user_read_callback_ = callback; 1148 user_read_callback_ = callback;
1114 } else { 1149 } else {
1115 user_read_buf_ = NULL; 1150 user_read_buf_ = NULL;
1116 user_read_buf_len_ = 0; 1151 user_read_buf_len_ = 0;
1117 1152
1118 if (!OnNetworkTaskRunner()) { 1153 if (!OnNetworkTaskRunner()) {
1154 // Update |nss_is_closed_| and |nss_waiting_read_| from
1155 // NetworkTaskRunner because it runs in multi-threaded mode.
Ryan Sleevi 2013/01/23 01:46:20 nit: These comments are superflous Same throughou
Takashi Toyoshima 2013/01/23 06:53:02 Done.
1156 PostOrRunCallback(FROM_HERE, base::Bind(&Core::DidNSSRead, this, rv));
1157
1119 PostOrRunCallback(FROM_HERE, base::Bind(callback, rv)); 1158 PostOrRunCallback(FROM_HERE, base::Bind(callback, rv));
1120 return ERR_IO_PENDING; 1159 return ERR_IO_PENDING;
1160 } else {
1161 // Update |nss_is_closed_| directly because it runs in single-threaded
1162 // mode. |nss_waiting_read_| is not set.
Ryan Sleevi 2013/01/23 01:46:20 nit: These comments are superflous Same throughou
Takashi Toyoshima 2013/01/23 06:53:02 Done.
1163 DCHECK(!nss_waiting_read_);
1164 if (rv <= 0)
1165 nss_is_closed_ = true;
1121 } 1166 }
1122 } 1167 }
1123 1168
1124 return rv; 1169 return rv;
1125 } 1170 }
1126 1171
1127 int SSLClientSocketNSS::Core::Write(IOBuffer* buf, int buf_len, 1172 int SSLClientSocketNSS::Core::Write(IOBuffer* buf, int buf_len,
1128 const CompletionCallback& callback) { 1173 const CompletionCallback& callback) {
1129 if (!OnNSSTaskRunner()) { 1174 if (!OnNSSTaskRunner()) {
1130 DCHECK(OnNetworkTaskRunner()); 1175 DCHECK(OnNetworkTaskRunner());
1131 DCHECK(!detached_); 1176 DCHECK(!detached_);
1132 DCHECK(transport_); 1177 DCHECK(transport_);
1178 DCHECK(!nss_waiting_write_);
1133 1179
1180 nss_waiting_write_ = true;
1134 bool posted = nss_task_runner_->PostTask( 1181 bool posted = nss_task_runner_->PostTask(
1135 FROM_HERE, 1182 FROM_HERE,
1136 base::Bind(IgnoreResult(&Core::Write), this, make_scoped_refptr(buf), 1183 base::Bind(IgnoreResult(&Core::Write), this, make_scoped_refptr(buf),
1137 buf_len, callback)); 1184 buf_len, callback));
1138 int rv = posted ? ERR_IO_PENDING : ERR_ABORTED; 1185 if (!posted) {
1139 return rv; 1186 nss_is_closed_ = true;
1187 nss_waiting_write_ = false;
1188 }
1189 return posted ? ERR_IO_PENDING : ERR_ABORTED;
1140 } 1190 }
1141 1191
1142 DCHECK(OnNSSTaskRunner()); 1192 DCHECK(OnNSSTaskRunner());
1143 DCHECK(handshake_callback_called_); 1193 DCHECK(handshake_callback_called_);
1144 DCHECK_EQ(STATE_NONE, next_handshake_state_); 1194 DCHECK_EQ(STATE_NONE, next_handshake_state_);
1145 DCHECK(user_write_callback_.is_null()); 1195 DCHECK(user_write_callback_.is_null());
1146 DCHECK(user_connect_callback_.is_null()); 1196 DCHECK(user_connect_callback_.is_null());
1147 DCHECK(!user_write_buf_); 1197 DCHECK(!user_write_buf_);
1148 DCHECK(nss_bufs_); 1198 DCHECK(nss_bufs_);
1149 1199
1150 user_write_buf_ = buf; 1200 user_write_buf_ = buf;
1151 user_write_buf_len_ = buf_len; 1201 user_write_buf_len_ = buf_len;
1152 1202
1153 int rv = DoWriteLoop(OK); 1203 int rv = DoWriteLoop(OK);
1154 if (rv == ERR_IO_PENDING) { 1204 if (rv == ERR_IO_PENDING) {
1205 if (OnNetworkTaskRunner())
1206 nss_waiting_write_ = true;
1155 user_write_callback_ = callback; 1207 user_write_callback_ = callback;
1156 } else { 1208 } else {
1157 user_write_buf_ = NULL; 1209 user_write_buf_ = NULL;
1158 user_write_buf_len_ = 0; 1210 user_write_buf_len_ = 0;
1159 1211
1160 if (!OnNetworkTaskRunner()) { 1212 if (!OnNetworkTaskRunner()) {
1213 // Update |nss_is_closed_| and |nss_waiting_write_| from
1214 // NetworkTaskRunner because it runs in multi-threaded mode.
1215 PostOrRunCallback(FROM_HERE, base::Bind(&Core::DidNSSWrite, this, rv));
1216
1161 PostOrRunCallback(FROM_HERE, base::Bind(callback, rv)); 1217 PostOrRunCallback(FROM_HERE, base::Bind(callback, rv));
1162 return ERR_IO_PENDING; 1218 return ERR_IO_PENDING;
1219 } else {
1220 // Update |nss_is_closed_| directly because it runs in single-threaded
1221 // mode. |nss_waiting_write_| is not set.
1222 DCHECK(!nss_waiting_write_);
1223 if (rv < 0)
1224 nss_is_closed_ = true;
1163 } 1225 }
1164 } 1226 }
1165 1227
1166 return rv; 1228 return rv;
1167 } 1229 }
1168 1230
1231 bool SSLClientSocketNSS::Core::IsConnected() {
1232 DCHECK(OnNetworkTaskRunner());
1233 return !nss_is_closed_;
1234 }
1235
1236 bool SSLClientSocketNSS::Core::HasPendingAsyncOperation() {
1237 DCHECK(OnNetworkTaskRunner());
1238 return nss_waiting_read_ || nss_waiting_write_;
1239 }
1240
1241 bool SSLClientSocketNSS::Core::HasUnhandledReceivedData() {
1242 DCHECK(OnNetworkTaskRunner());
1243 return unhandled_buffer_size_ != 0;
1244 }
1245
1169 bool SSLClientSocketNSS::Core::OnNSSTaskRunner() const { 1246 bool SSLClientSocketNSS::Core::OnNSSTaskRunner() const {
1170 return nss_task_runner_->RunsTasksOnCurrentThread(); 1247 return nss_task_runner_->RunsTasksOnCurrentThread();
1171 } 1248 }
1172 1249
1173 bool SSLClientSocketNSS::Core::OnNetworkTaskRunner() const { 1250 bool SSLClientSocketNSS::Core::OnNetworkTaskRunner() const {
1174 return network_task_runner_->RunsTasksOnCurrentThread(); 1251 return network_task_runner_->RunsTasksOnCurrentThread();
1175 } 1252 }
1176 1253
1177 // static 1254 // static
1178 SECStatus SSLClientSocketNSS::Core::OwnAuthCertHandler( 1255 SECStatus SSLClientSocketNSS::Core::OwnAuthCertHandler(
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after
2037 GotoState(STATE_HANDSHAKE); 2114 GotoState(STATE_HANDSHAKE);
2038 return OK; 2115 return OK;
2039 } 2116 }
2040 2117
2041 int SSLClientSocketNSS::Core::DoPayloadRead() { 2118 int SSLClientSocketNSS::Core::DoPayloadRead() {
2042 DCHECK(OnNSSTaskRunner()); 2119 DCHECK(OnNSSTaskRunner());
2043 DCHECK(user_read_buf_); 2120 DCHECK(user_read_buf_);
2044 DCHECK_GT(user_read_buf_len_, 0); 2121 DCHECK_GT(user_read_buf_len_, 0);
2045 2122
2046 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); 2123 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
2124 // Update NSSTaskRunner status because PR_Read may consume |nss_bufs_|, then
2125 // following |amount_in_read_buffer| may be changed here.
2126 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_);
2127 base::Closure task = base::Bind(
2128 &Core::OnNSSTaskRunnerStateUpdated,
2129 this,
2130 amount_in_read_buffer,
2131 rv <= 0 && rv != ERR_IO_PENDING,
2132 OPERATION_UPDATE,
2133 base::Closure());
Takashi Toyoshima 2013/01/23 06:53:02 Oops, I missed to post the created task... then DC
2134
2047 if (client_auth_cert_needed_) { 2135 if (client_auth_cert_needed_) {
2048 // We don't need to invalidate the non-client-authenticated SSL session 2136 // We don't need to invalidate the non-client-authenticated SSL session
2049 // because the server will renegotiate anyway. 2137 // because the server will renegotiate anyway.
2050 rv = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 2138 rv = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
2051 PostOrRunCallback( 2139 PostOrRunCallback(
2052 FROM_HERE, 2140 FROM_HERE,
2053 base::Bind(&AddLogEventWithCallback, weak_net_log_, 2141 base::Bind(&AddLogEventWithCallback, weak_net_log_,
2054 NetLog::TYPE_SSL_READ_ERROR, 2142 NetLog::TYPE_SSL_READ_ERROR,
2055 CreateNetLogSSLErrorCallback(rv, 0))); 2143 CreateNetLogSSLErrorCallback(rv, 0)));
2056 return rv; 2144 return rv;
(...skipping 17 matching lines...) Expand all
2074 NetLog::TYPE_SSL_READ_ERROR, 2162 NetLog::TYPE_SSL_READ_ERROR,
2075 CreateNetLogSSLErrorCallback(rv, prerr))); 2163 CreateNetLogSSLErrorCallback(rv, prerr)));
2076 return rv; 2164 return rv;
2077 } 2165 }
2078 2166
2079 int SSLClientSocketNSS::Core::DoPayloadWrite() { 2167 int SSLClientSocketNSS::Core::DoPayloadWrite() {
2080 DCHECK(OnNSSTaskRunner()); 2168 DCHECK(OnNSSTaskRunner());
2081 2169
2082 DCHECK(user_write_buf_); 2170 DCHECK(user_write_buf_);
2083 2171
2172 int old_amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_);
2084 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); 2173 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
2174 int new_amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_);
2175 // PR_Write could potentially consume the unhandled data in the memio read
2176 // buffer if a renegotiation is in progress. If the buffer is consumed,
2177 // notify the latest buffer size to NetworkRunner.
2178 if (old_amount_in_read_buffer != new_amount_in_read_buffer) {
2179 base::Closure task = base::Bind(
2180 &Core::OnNSSTaskRunnerStateUpdated,
2181 this,
2182 new_amount_in_read_buffer,
2183 false,
2184 OPERATION_UPDATE,
2185 base::Closure());
2186 }
2085 if (rv >= 0) { 2187 if (rv >= 0) {
2086 PostOrRunCallback( 2188 PostOrRunCallback(
2087 FROM_HERE, 2189 FROM_HERE,
2088 base::Bind(&LogByteTransferEvent, weak_net_log_, 2190 base::Bind(&LogByteTransferEvent, weak_net_log_,
2089 NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv, 2191 NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv,
2090 scoped_refptr<IOBuffer>(user_write_buf_))); 2192 scoped_refptr<IOBuffer>(user_write_buf_)));
2091 return rv; 2193 return rv;
2092 } 2194 }
2093 PRErrorCode prerr = PR_GetError(); 2195 PRErrorCode prerr = PR_GetError();
2094 if (prerr == PR_WOULD_BLOCK_ERROR) 2196 if (prerr == PR_WOULD_BLOCK_ERROR)
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2280 PostOrRunCallback(FROM_HERE, c); 2382 PostOrRunCallback(FROM_HERE, c);
2281 } 2383 }
2282 2384
2283 void SSLClientSocketNSS::Core::DoReadCallback(int rv) { 2385 void SSLClientSocketNSS::Core::DoReadCallback(int rv) {
2284 DCHECK(OnNSSTaskRunner()); 2386 DCHECK(OnNSSTaskRunner());
2285 DCHECK_NE(ERR_IO_PENDING, rv); 2387 DCHECK_NE(ERR_IO_PENDING, rv);
2286 DCHECK(!user_read_callback_.is_null()); 2388 DCHECK(!user_read_callback_.is_null());
2287 2389
2288 user_read_buf_ = NULL; 2390 user_read_buf_ = NULL;
2289 user_read_buf_len_ = 0; 2391 user_read_buf_len_ = 0;
2290 base::Closure c = base::Bind( 2392 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_);
2291 base::ResetAndReturn(&user_read_callback_), 2393 // This will invoke the user callback with |rv| as result.
2292 rv); 2394 base::Closure user_cb = base::Bind(
2293 PostOrRunCallback(FROM_HERE, c); 2395 base::ResetAndReturn(&user_read_callback_), rv);
2396 // This is used to curry the |amount_int_read_buffer| and |user_cb| back to
2397 // the network task runner.
2398 base::Closure task = base::Bind(
2399 &Core::OnNSSTaskRunnerStateUpdated,
2400 this,
2401 amount_in_read_buffer,
2402 rv <= 0, // EOF or errors.
2403 OPERATION_READ,
2404 user_cb);
2405 PostOrRunCallback(FROM_HERE, task);
2294 } 2406 }
2295 2407
2296 void SSLClientSocketNSS::Core::DoWriteCallback(int rv) { 2408 void SSLClientSocketNSS::Core::DoWriteCallback(int rv) {
2297 DCHECK(OnNSSTaskRunner()); 2409 DCHECK(OnNSSTaskRunner());
2298 DCHECK_NE(ERR_IO_PENDING, rv); 2410 DCHECK_NE(ERR_IO_PENDING, rv);
2299 DCHECK(!user_write_callback_.is_null()); 2411 DCHECK(!user_write_callback_.is_null());
2300 2412
2301 // Since Run may result in Write being called, clear |user_write_callback_| 2413 // Since Run may result in Write being called, clear |user_write_callback_|
2302 // up front. 2414 // up front.
2303 user_write_buf_ = NULL; 2415 user_write_buf_ = NULL;
2304 user_write_buf_len_ = 0; 2416 user_write_buf_len_ = 0;
2305 base::Closure c = base::Bind( 2417 // Update buffer status because DoWriteLoop called DoTransportIO which may
2306 base::ResetAndReturn(&user_write_callback_), 2418 // perform read operations.
2307 rv); 2419 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_);
2308 PostOrRunCallback(FROM_HERE, c); 2420 // This will invoke the user callback with |rv| as result.
2421 base::Closure user_cb = base::Bind(
2422 base::ResetAndReturn(&user_write_callback_), rv);
2423 // This is used to curry the |amount_int_read_buffer| and |user_cb| back to
2424 // the network task runner.
2425 base::Closure task = base::Bind(
2426 &Core::OnNSSTaskRunnerStateUpdated,
2427 this,
2428 amount_in_read_buffer,
2429 rv < 0, // Errors.
2430 OPERATION_WRITE,
2431 user_cb);
2432 PostOrRunCallback(FROM_HERE, task);
2309 } 2433 }
2310 2434
2311 SECStatus SSLClientSocketNSS::Core::ClientChannelIDHandler( 2435 SECStatus SSLClientSocketNSS::Core::ClientChannelIDHandler(
2312 void* arg, 2436 void* arg,
2313 PRFileDesc* socket, 2437 PRFileDesc* socket,
2314 SECKEYPublicKey **out_public_key, 2438 SECKEYPublicKey **out_public_key,
2315 SECKEYPrivateKey **out_private_key) { 2439 SECKEYPrivateKey **out_private_key) {
2316 Core* core = reinterpret_cast<Core*>(arg); 2440 Core* core = reinterpret_cast<Core*>(arg);
2317 DCHECK(core->OnNSSTaskRunner()); 2441 DCHECK(core->OnNSSTaskRunner());
2318 2442
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 } 2682 }
2559 2683
2560 int SSLClientSocketNSS::Core::DoBufferSend(IOBuffer* send_buffer, int len) { 2684 int SSLClientSocketNSS::Core::DoBufferSend(IOBuffer* send_buffer, int len) {
2561 DCHECK(OnNetworkTaskRunner()); 2685 DCHECK(OnNetworkTaskRunner());
2562 DCHECK_GT(len, 0); 2686 DCHECK_GT(len, 0);
2563 2687
2564 if (detached_) 2688 if (detached_)
2565 return ERR_ABORTED; 2689 return ERR_ABORTED;
2566 2690
2567 int rv = transport_->socket()->Write( 2691 int rv = transport_->socket()->Write(
2568 send_buffer, len, 2692 send_buffer, len,
2569 base::Bind(&Core::BufferSendComplete, 2693 base::Bind(&Core::BufferSendComplete,
2570 base::Unretained(this))); 2694 base::Unretained(this)));
2571 2695
2572 if (!OnNSSTaskRunner() && rv != ERR_IO_PENDING) { 2696 if (!OnNSSTaskRunner() && rv != ERR_IO_PENDING) {
2573 nss_task_runner_->PostTask( 2697 nss_task_runner_->PostTask(
2574 FROM_HERE, 2698 FROM_HERE,
2575 base::Bind(&Core::BufferSendComplete, this, rv)); 2699 base::Bind(&Core::BufferSendComplete, this, rv));
2576 return rv; 2700 return rv;
2577 } 2701 }
2578 2702
2579 return rv; 2703 return rv;
2580 } 2704 }
(...skipping 22 matching lines...) Expand all
2603 FROM_HERE, 2727 FROM_HERE,
2604 base::Bind(&Core::OnHandshakeIOComplete, this, rv)); 2728 base::Bind(&Core::OnHandshakeIOComplete, this, rv));
2605 return ERR_IO_PENDING; 2729 return ERR_IO_PENDING;
2606 } 2730 }
2607 2731
2608 return rv; 2732 return rv;
2609 } 2733 }
2610 2734
2611 void SSLClientSocketNSS::Core::OnHandshakeStateUpdated( 2735 void SSLClientSocketNSS::Core::OnHandshakeStateUpdated(
2612 const HandshakeState& state) { 2736 const HandshakeState& state) {
2737 DCHECK(OnNetworkTaskRunner());
2613 network_handshake_state_ = state; 2738 network_handshake_state_ = state;
2614 } 2739 }
2615 2740
2741 void SSLClientSocketNSS::Core::OnNSSTaskRunnerStateUpdated(
Ryan Sleevi 2013/01/23 01:46:20 I find it weird to have both this function and Did
2742 int amount_in_read_buffer,
2743 bool closed,
2744 Operation operation,
2745 const base::Closure& callback) {
2746 DCHECK(OnNetworkTaskRunner());
2747 DCHECK(operation == OPERATION_UPDATE || !callback.is_null());
2748 DCHECK((operation == OPERATION_READ && nss_waiting_read_) ||
2749 (operation == OPERATION_WRITE && nss_waiting_write_) ||
2750 operation == OPERATION_UPDATE);
2751
2752 unhandled_buffer_size_ = amount_in_read_buffer;
2753 if (closed)
2754 nss_is_closed_ = true;
2755 if (operation == OPERATION_READ)
2756 nss_waiting_read_ = false;
2757 else if (operation == OPERATION_WRITE)
2758 nss_waiting_write_ = false;
2759
2760 if (operation != OPERATION_UPDATE)
2761 callback.Run();
2762 }
2763
2764 void SSLClientSocketNSS::Core::DidNSSRead(int result) {
2765 DCHECK(OnNetworkTaskRunner());
2766 DCHECK(nss_waiting_read_);
2767 nss_waiting_read_ = false;
2768 if (result <= 0)
2769 nss_is_closed_ = true;
2770 }
2771
2772 void SSLClientSocketNSS::Core::DidNSSWrite(int result) {
2773 DCHECK(OnNetworkTaskRunner());
2774 DCHECK(nss_waiting_write_);
2775 nss_waiting_write_ = false;
2776 if (result < 0)
2777 nss_is_closed_ = true;
2778 }
2779
2616 void SSLClientSocketNSS::Core::BufferSendComplete(int result) { 2780 void SSLClientSocketNSS::Core::BufferSendComplete(int result) {
2617 if (!OnNSSTaskRunner()) { 2781 if (!OnNSSTaskRunner()) {
2618 if (detached_) 2782 if (detached_)
2619 return; 2783 return;
2620 2784
2621 nss_task_runner_->PostTask( 2785 nss_task_runner_->PostTask(
2622 FROM_HERE, base::Bind(&Core::BufferSendComplete, this, result)); 2786 FROM_HERE, base::Bind(&Core::BufferSendComplete, this, result));
2623 return; 2787 return;
2624 } 2788 }
2625 2789
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
2915 user_connect_callback_.Reset(); 3079 user_connect_callback_.Reset();
2916 server_cert_verify_result_.Reset(); 3080 server_cert_verify_result_.Reset();
2917 completed_handshake_ = false; 3081 completed_handshake_ = false;
2918 start_cert_verification_time_ = base::TimeTicks(); 3082 start_cert_verification_time_ = base::TimeTicks();
2919 InitCore(); 3083 InitCore();
2920 3084
2921 LeaveFunction(""); 3085 LeaveFunction("");
2922 } 3086 }
2923 3087
2924 bool SSLClientSocketNSS::IsConnected() const { 3088 bool SSLClientSocketNSS::IsConnected() const {
2925 // Ideally, we should also check if we have received the close_notify alert
2926 // message from the server, and return false in that case. We're not doing
2927 // that, so this function may return a false positive. Since the upper
2928 // layer (HttpNetworkTransaction) needs to handle a persistent connection
2929 // closed by the server when we send a request anyway, a false positive in
2930 // exchange for simpler code is a good trade-off.
2931 EnterFunction(""); 3089 EnterFunction("");
2932 bool ret = completed_handshake_ && transport_->socket()->IsConnected(); 3090 bool ret = completed_handshake_ &&
3091 (core_->HasPendingAsyncOperation() ||
3092 (core_->IsConnected() && core_->HasUnhandledReceivedData()) ||
3093 transport_->socket()->IsConnected());
2933 LeaveFunction(""); 3094 LeaveFunction("");
2934 return ret; 3095 return ret;
2935 } 3096 }
2936 3097
2937 bool SSLClientSocketNSS::IsConnectedAndIdle() const { 3098 bool SSLClientSocketNSS::IsConnectedAndIdle() const {
2938 // Unlike IsConnected, this method doesn't return a false positive.
2939 //
2940 // Strictly speaking, we should check if we have received the close_notify
2941 // alert message from the server, and return false in that case. Although
2942 // the close_notify alert message means EOF in the SSL layer, it is just
2943 // bytes to the transport layer below, so
2944 // transport_->socket()->IsConnectedAndIdle() returns the desired false
2945 // when we receive close_notify.
2946 EnterFunction(""); 3099 EnterFunction("");
2947 bool ret = completed_handshake_ && transport_->socket()->IsConnectedAndIdle(); 3100 bool ret = IsConnected() &&
3101 !(core_->IsConnected() && core_->HasUnhandledReceivedData()) &&
Ryan Sleevi 2013/01/23 01:46:20 In thinking through this logic more, perhaps it sh
Takashi Toyoshima 2013/01/23 06:53:02 Agreed. I give up to reuse IsConnected() here.
3102 transport_->socket()->IsConnectedAndIdle();
2948 LeaveFunction(""); 3103 LeaveFunction("");
2949 return ret; 3104 return ret;
2950 } 3105 }
2951 3106
2952 int SSLClientSocketNSS::GetPeerAddress(IPEndPoint* address) const { 3107 int SSLClientSocketNSS::GetPeerAddress(IPEndPoint* address) const {
2953 return transport_->socket()->GetPeerAddress(address); 3108 return transport_->socket()->GetPeerAddress(address);
2954 } 3109 }
2955 3110
2956 int SSLClientSocketNSS::GetLocalAddress(IPEndPoint* address) const { 3111 int SSLClientSocketNSS::GetLocalAddress(IPEndPoint* address) const {
2957 return transport_->socket()->GetLocalAddress(address); 3112 return transport_->socket()->GetLocalAddress(address);
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
3491 EnsureThreadIdAssigned(); 3646 EnsureThreadIdAssigned();
3492 base::AutoLock auto_lock(lock_); 3647 base::AutoLock auto_lock(lock_);
3493 return valid_thread_id_ == base::PlatformThread::CurrentId(); 3648 return valid_thread_id_ == base::PlatformThread::CurrentId();
3494 } 3649 }
3495 3650
3496 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { 3651 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const {
3497 return server_bound_cert_service_; 3652 return server_bound_cert_service_;
3498 } 3653 }
3499 3654
3500 } // namespace net 3655 } // namespace net
OLDNEW
« no previous file with comments | « net/data/websocket/split_packet_check.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698