TLS相关
raymondheavy opened this issue · 9 comments
raymondheavy commented
baseconnect.go这个文件中
_```
// Read 读取数据
func (c *BaseConnect) Read(bs []byte) (int, error) {
n, err := unix.Read(c.fd, bs)
// 已完成了TLS握手
if c.handshakeCompleted {
if n >= 0 {
c.tlsRawSize += n
}
}
想问下,if c.handshakeCompleted后计算收到的业务数据长度。有没有一种可能性,就是在握手结束时最后一次Read会读取部分业务数据?
ikilobyte commented
如果c.handshakeCompleted
为true
,那就一定完成了TLS握手,如果false
则还在握手阶段,不会出现握手结束时最后一次Read会读取部分业务数据
TLS握手实现细节
Lines 84 to 103 in 3ce691c
tlsConnect.Handshake()
实际上是调用的标准库的方法,标准库的conn
会调用baseConnect.Read
,此时c.handshakeCompleted
一定是false,欢迎交流
raymondheavy commented
if err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
if e, ok := err.(net.Error); !ok || !e.Temporary() {
c.in.setErrorLocked(err)
}
return err
}
// ReadFrom reads data from r until EOF and appends it to the buffer, growing
// the buffer as needed. The return value n is the number of bytes read. Any
// error except io.EOF encountered during the read is also returned. If the
// buffer becomes too large, ReadFrom will panic with ErrTooLarge.
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
b.lastRead = opInvalid
for {
i := b.grow(MinRead)
b.buf = b.buf[:i]
m, e := r.Read(b.buf[i:cap(b.buf)])
if m < 0 {
panic(errNegativeRead)
}
b.buf = b.buf[:i+m]
n += int64(m)
if e == io.EOF {
return n, nil // e is EOF, so return nil explicitly
}
if e != nil {
return n, e
}
}
}
在标准库tls中,read传入的buf大小不一定就是最后一次需要的大小,可能是大于这个需要数据大小的吧。如果对端在握手最后一次交互后,立即发送了业务数据。此时socket缓冲区中既有握手,也有业务数据,如果read传入的读buf大于剩余的握手大小,不就把业务数据也读取了吗?
raymondheavy commented
ikilobyte commented
在使用TLS后,应用层的read操作并不是直接从socket中读取,而是从TLS层的buf中读取,流程就变成了 app -> tls -> socket
ikilobyte commented
即使tls在握手时读了应用层的业务数据,tls也会保存在buf中,应用层写数据也是一样的,先到写到tls层,tls加密后再发送出去
ikilobyte commented
raymondheavy commented
那如果读了,c.tlsRawSize 这个值的准确性呢?
ikilobyte commented
这个值确实不准了,是遇到了什么问题吗
raymondheavy commented
主要是想学习下,如何精确切分握手和后续的业务数据的。看了代码之后,对这个地方有些疑问