[Feature]: tls support
Rohsichan opened this issue · comments
Rohsichan commented
Description of new feature
For now, I've only implemented Read, and I think I'll just do the same for Write.
I've implemented it by converting gnet.Conn -> tls.Conn.
Scenarios for new feature
If implemented as follows, we have confirmed that tls have been decoded normally.
func (hs *httpServer) OnTraffic(c gnet.Conn) gnet.Action {
fmt.Printf("gnet is OnTraffic Handler FD %d\n", c.Fd())
fmt.Println("=================================")
buf := make([]byte, 32*1024)
_, err := c.Read(buf)
if err != nil {
panic(err)
}
fmt.Println(string(buf))
fmt.Println("=================================")
return gnet.None
}
When requesting tls, the onTraffic function checked the decryption content normally.
Breaking changes or not?
No
Code snippets (optional)
// tlsconfig options support
func WithTlsConfig(config *tls.Config) Option {
return func(opts *Options) {
opts.Tlsconfig = config
}
}
// gent conn tlsconn, tlscheck add
type conn struct {
fd int // file descriptor
gfd gfd.GFD // gnet file descriptor
ctx interface{} // user-defined context
remote unix.Sockaddr // remote socket address
localAddr net.Addr // local addr
remoteAddr net.Addr // remote addr
loop *eventloop // connected event-loop
outboundBuffer elastic.Buffer // buffer for data that is eligible to be sent to the remote
pollAttachment netpoll.PollAttachment // connection attachment for poller
inboundBuffer elastic.RingBuffer // buffer for leftover data from the remote
buffer []byte // buffer for the latest bytes
isDatagram bool // UDP protocol
opened bool // connection opened event fired
isEOF bool // whether the connection has reached EOF
tlsconn *tls.Conn // is tlsconn
tlscheck bool // tls check
}
// eventloop_unix.go Read Func change
loop:
if tlsconfig != nil && !c.tlscheck {
buf := make([]byte, 1)
_, _, err := unix.Recvfrom(c.fd, buf, unix.MSG_PEEK)
if err != nil {
return el.close(c, os.NewSyscallError("peek", err))
}
// 0x80: sslv2
// 0x16: sslv3, TLSv1
if buf[0] == 0x80 || buf[0] == 0x16 {
/* is tls */
file := os.NewFile(uintptr(c.fd), "fd")
conn, err := net.FileConn(file)
if err != nil {
return el.close(c, fmt.Errorf("fileconn is error"))
}
c.tlsconn = tls.Server(conn, tlsconfig)
c.tlscheck = true
err = c.tlsconn.Handshake()
if err != nil {
return el.close(c, fmt.Errorf("is handshake Error ", err))
}
return nil
} else {
c.tlscheck = true
}
}
if c.tlsconn != nil && !c.tlsconn.ConnectionState().HandshakeComplete {
err := c.tlsconn.Handshake()
if err != nil {
return el.close(c, fmt.Errorf("is handshake Error ", err))
}
return nil
}
var n int
var err error
if c.tlsconn != nil {
n, err = c.tlsconn.Read(el.buffer)
} else {
n, err = unix.Read(c.fd, el.buffer)
}
Alternatives for new feature
None.
Additional context (optional)
None.
Rohsichan commented
Recv Peek referred to 0x80, 0x16 code for code nginx.
Rohsichan commented
Thank you for your reply, I will refer to it.
gh-translator commented