Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: tls support #614

Closed
Rohsichan opened this issue Jun 21, 2024 · 5 comments
Closed

[Feature]: tls support #614

Rohsichan opened this issue Jun 21, 2024 · 5 comments
Assignees
Labels
enhancement New feature or request proposal Proposal for this repo

Comments

@Rohsichan
Copy link

Rohsichan commented Jun 21, 2024

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 Rohsichan added enhancement New feature or request proposal Proposal for this repo labels Jun 21, 2024
@Rohsichan
Copy link
Author

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

@panjf2000
Copy link
Owner

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

@Rohsichan
Copy link
Author

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

@panjf2000
Copy link
Owner

Duplicate #16

@gh-translator
Copy link
Collaborator

🤖 Non-English text detected, translating...


Duplicate #16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request proposal Proposal for this repo
Projects
None yet
Development

No branches or pull requests

3 participants