summaryrefslogtreecommitdiff
path: root/src/WinTLSSession.h
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2016-11-11 22:20:29 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2016-11-12 22:20:41 +0900
commitd974c935cdfd90ffe412e287cef058377a55e755 (patch)
tree751a88c68b42340d6fdf32da1d44528c0c28230c /src/WinTLSSession.h
parentd289dc1108324ff5589ab103ef0863faaa3c5de1 (diff)
WinTLS: Rewrite writeDatarefactor-wintls-write
We re-wrote WinTLSSession::writeData. The major points are: * Buffer is now preallocated once handshake is finished. Previously, they are allocated each time when we send one TLS record. * Schannel uses header, body and trailer for each secBuffer. Now we send them off at once using WSASend which is windows counterpart of sendv. Previously, we do memmove if some of them are truncated. * We don't try to send application data in WinTLSSession::closeConnection, since semantically we need same application data used to create TLS record before. Using 0 length data to finish sending buffered data looks like a hack.
Diffstat (limited to 'src/WinTLSSession.h')
-rw-r--r--src/WinTLSSession.h44
1 files changed, 40 insertions, 4 deletions
diff --git a/src/WinTLSSession.h b/src/WinTLSSession.h
index 2db9cb21..9095bed2 100644
--- a/src/WinTLSSession.h
+++ b/src/WinTLSSession.h
@@ -100,6 +100,18 @@ public:
};
} // namespace wintls
+class TLSBuffer : public ::SecBuffer {
+public:
+ TLSBuffer() : ::SecBuffer{}{}
+
+ explicit TLSBuffer(ULONG type, ULONG size, void* data)
+ {
+ cbBuffer = size;
+ BufferType = type;
+ pvBuffer = data;
+ }
+};
+
class WinTLSSession : public TLSSession {
enum state_t {
st_constructed,
@@ -172,16 +184,31 @@ public:
virtual size_t getRecvBufferedLength() CXX11_OVERRIDE;
private:
+ // Obtains TLS record size limits. This function returns 0 if it
+ // succeeds, or -1. status_ and state_ are updated according to the
+ // result.
+ int obtainTLSRecordSizes();
+ // Ensures the buffer size so that maximum TLS record can be sent.
+ void ensureSendBuffer();
+ // Sends TLS record specified in sendRecordBuffers_. It uses
+ // recordBytesSent_ to track down how many bytes have been sent.
+ // This function returns 0 if it succeeds, or negative error codes.
+ int sendTLSRecord();
+ // Returns the number of bytes in the remaining TLS record size.
+ size_t getLeftTLSRecordSize() const;
+
std::string hostname_;
sock_t sockfd_;
TLSSessionSide side_;
CredHandle* cred_;
CtxtHandle handle_;
- // Buffer for already encrypted writes
+ // Buffer for already encrypted writes. This is only used in
+ // handshake.
wintls::Buffer writeBuf_;
- // While the writeBuf_ holds encrypted messages, writeBuffered_ has the
- // corresponding size of unencrypted data used to produce the messages.
+ // While the sendRecordBuffers_ holds encrypted messages,
+ // writeBuffered_ has the corresponding size of unencrypted data
+ // used to produce the messages.
size_t writeBuffered_;
// Buffer for still encrypted reads
wintls::Buffer readBuf_;
@@ -191,7 +218,16 @@ private:
state_t state_;
SECURITY_STATUS status_;
- std::unique_ptr<SecPkgContext_StreamSizes> streamSizes_;
+ // The number of maximum size for TLS record header, body, and
+ // trailer.
+ SecPkgContext_StreamSizes streamSizes_;
+ // Underlying buffer for outgoing TLS record.
+ std::vector<unsigned char> sendBuffer_;
+ // How many bytes has been sent for current TLS record held in
+ // sendRecordBuffers_.
+ size_t recordBytesSent_;
+ // This holds current outgoing TLS record.
+ std::array<TLSBuffer, 4> sendRecordBuffers_;
};
} // namespace aria2