package faketls
import (
"bytes"
"io"
"sync"
"github.com/go-faster/errors"
"github.com/gotd/td/clock"
"github.com/gotd/td/internal/mtproxy"
)
type FakeTLS struct {
rand io .Reader
clock clock .Clock
conn io .ReadWriter
version [2 ]byte
firstPacket bool
readBuf bytes .Buffer
readBufMux sync .Mutex
}
func NewFakeTLS (r io .Reader , conn io .ReadWriter ) *FakeTLS {
return &FakeTLS {
rand : r ,
clock : clock .System ,
conn : conn ,
version : Version12Bytes ,
readBuf : bytes .Buffer {},
}
}
func (o *FakeTLS ) Handshake (protocol [4 ]byte , dc int , s mtproxy .Secret ) error {
o .readBufMux .Lock ()
o .readBuf .Reset ()
o .readBufMux .Unlock ()
var sessionID [32 ]byte
if _ , err := o .rand .Read (sessionID [:]); err != nil {
return errors .Wrap (err , "generate sessionID" )
}
clientDigest , err := writeClientHello (o .conn , o .clock , sessionID , s .CloakHost , s .Secret )
if err != nil {
return errors .Wrap (err , "send ClientHello" )
}
if err := readServerHello (o .conn , clientDigest , s .Secret ); err != nil {
return errors .Wrap (err , "receive ServerHello" )
}
return nil
}
func (o *FakeTLS ) Write (b []byte ) (n int , err error ) {
if !o .firstPacket {
_, err = writeRecord (o .conn , record {
Type : RecordTypeChangeCipherSpec ,
Version : o .version ,
Data : []byte ("\x01" ),
})
if err != nil {
return 0 , errors .Wrap (err , "write first TLS packet" )
}
o .firstPacket = true
}
n , err = writeRecord (o .conn , record {
Type : RecordTypeApplication ,
Version : o .version ,
Data : b ,
})
if err != nil {
return 0 , errors .Wrap (err , "write TLS record" )
}
return
}
func (o *FakeTLS ) Read (b []byte ) (n int , err error ) {
o .readBufMux .Lock ()
defer o .readBufMux .Unlock ()
if o .readBuf .Len () > 0 {
return o .readBuf .Read (b )
}
rec , err := readRecord (o .conn )
if err != nil {
return 0 , errors .Wrap (err , "read TLS record" )
}
switch rec .Type {
case RecordTypeChangeCipherSpec :
case RecordTypeApplication :
case RecordTypeHandshake :
return 0 , errors .New ("unexpected record type handshake" )
default :
return 0 , errors .Errorf ("unsupported record type %v" , rec .Type )
}
o .readBuf .Write (rec .Data )
return o .readBuf .Read (b )
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .