panjf2000 / gnet

🚀 gnet is a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go.

Home Page:https://gnet.host

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature]: tls support

Rohsichan opened this issue · comments

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.

Recv Peek referred to 0x80, 0x16 code for code nginx.

Note that there is a WIP PR #565 for TLS.

Thank you for your reply, I will refer to it.

Duplicate #16

🤖 Non-English text detected, translating...


Duplicate #16