Apologies - didn’t look closely - it doesn’t appear the buffer in the connection is used at all. I suspect though if you read the wolfssl api that the implementation may be async - meaning the data must remain referenced until it is sent.
> On Dec 2, 2024, at 11:38 AM, robert engels <reng...@ix.netcom.com> wrote: > > You are using the same buffer for reading and writing - I suspect that is > your problem... > >> On Dec 2, 2024, at 11:00 AM, Lealem Amedie <lealemt...@gmail.com> wrote: >> >> Hi, >> >> I’m trying to get an https server working by overwriting the >> accept/read/write methods in the http module. I’m using go-wolfssl for TLS. >> >> The server will accept a TLS 1.2 connection, then send some random data to >> the client connects, then wait for another connection. >> >> The issue that I’m seeing is that whenever the server sends large payloads, >> it’ll do that successfully but it then can’t send data to the next client >> that connects (the send errors out with the TCP error EBADF). If dealing >> with smaller payloads (<30k), the server can send data successfully to each >> client that connects. Then as soon as a large one is sent, the next >> transmission fails. >> >> If I disable the GOGC with debug.SetGCPercent(-1), the issue goes away and I >> can send as many large payloads as required. From the debugging I’ve done so >> far, this looks like an issue with the GO garbage collector dropping C >> pointers. go-wolfssl relies on the wolfSSL C library so it uses CGO. Does >> anyone have any other ideas or input? >> >> Code is below. See this repo to actually run it GitHub - >> lealem47/go-wolfssl-https-server >> <https://github.com/lealem47/go-wolfssl-https-server/> >> Thank you! >> >> >> >> ``` >> >> package main >> >> import ( >> "bytes" >> "crypto/rand" >> "encoding/base64" >> "fmt" >> log "github.com/sirupsen/logrus" >> wolfSSL "github.com/wolfssl/go-wolfssl" >> "net" >> "net/http" >> "os" >> "strconv" >> "sync" >> "time" >> ) >> >> const defaultPort = "8443" >> >> type wolfSSLListener struct { >> listener net.Listener >> ctx *wolfSSL.WOLFSSL_CTX >> } >> >> // Accept waits for and returns the next connection to the listener. >> func (cl *wolfSSLListener) Accept() (net.Conn, error) { >> conn, err := cl.listener.Accept() >> if err != nil { >> return nil, err >> } >> fmt.Println("Accepted new connection from:", conn.RemoteAddr()) >> >> ssl := wolfSSL.WolfSSL_new(cl.ctx) >> if ssl == nil { >> fmt.Println("WolfSSL_new Failed") >> os.Exit(1) >> } >> >> file, err := conn.(*net.TCPConn).File() >> if err != nil { >> panic(err) >> } >> fd := file.Fd() >> wolfSSL.WolfSSL_set_fd(ssl, int(fd)) >> >> ret := wolfSSL.WolfSSL_accept(ssl) >> if ret != wolfSSL.WOLFSSL_SUCCESS { >> fmt.Println("WolfSSL_accept error ", ret) >> } else { >> fmt.Println("Client Successfully Connected!") >> } >> >> return &wolfSSLConn{ >> conn: conn, >> ssl: ssl, >> }, nil >> } >> >> // Close closes the listener, making it stop accepting new connections. >> func (cl *wolfSSLListener) Close() error { >> fmt.Println("Closing listener...") >> return cl.listener.Close() >> } >> >> // Addr returns the listener's network address. >> func (cl *wolfSSLListener) Addr() net.Addr { >> return cl.listener.Addr() >> } >> >> type wolfSSLConn struct { >> conn net.Conn >> ssl *wolfSSL.WOLFSSL >> buffer bytes.Buffer >> mu sync.Mutex >> closed bool >> } >> >> func (w *wolfSSLConn) Read(b []byte) (int, error) { >> log.Infof("Calling read: %d", len(b)) >> >> ret := wolfSSL.WolfSSL_read(w.ssl, b, uintptr(len(b))) >> if ret < 0 { >> errCode := wolfSSL.WolfSSL_get_error(w.ssl, int(ret)) >> return 0, fmt.Errorf("read error: %d", errCode) >> } >> >> log.Infof("Read bytes: %s", string(b[:ret])) >> return int(ret), nil >> } >> >> func (w *wolfSSLConn) Write(b []byte) (int, error) { >> log.Infof("Calling write: %d", len(b)) >> >> sz := uintptr(len(b)) >> >> ret := wolfSSL.WolfSSL_write(w.ssl, b, sz) >> if ret < 0 { >> errCode := wolfSSL.WolfSSL_get_error(w.ssl, int(ret)) >> return 0, fmt.Errorf("write error: %d", errCode) >> } >> >> return int(ret), nil >> } >> >> func (w *wolfSSLConn) Close() error { >> log.Infof("Closing connection") >> >> wolfSSL.WolfSSL_shutdown(w.ssl) >> wolfSSL.WolfSSL_free(w.ssl) >> return w.conn.Close() >> } >> >> func (w *wolfSSLConn) LocalAddr() net.Addr { >> return w.conn.LocalAddr() >> } >> >> func (w *wolfSSLConn) RemoteAddr() net.Addr { >> return w.conn.RemoteAddr() >> } >> >> func (w *wolfSSLConn) SetDeadline(t time.Time) error { >> return w.conn.SetDeadline(t) >> } >> >> func (w *wolfSSLConn) SetReadDeadline(t time.Time) error { >> return w.conn.SetReadDeadline(t) >> } >> >> func (w *wolfSSLConn) SetWriteDeadline(t time.Time) error { >> return w.conn.SetWriteDeadline(t) >> } >> >> // Handler for generating and base64 encoding 5KB of random data >> func randomDataHandler(w http.ResponseWriter, r *http.Request) { >> // Get the "size" query parameter from the request >> sizeParam := r.URL.Query().Get("size") >> size := 500000 // default size >> >> // If the "size" parameter is provided, convert it to an integer >> if sizeParam != "" { >> parsedSize, err := strconv.Atoi(sizeParam) >> if err != nil || parsedSize <= 0 { >> http.Error(w, "Invalid size parameter", >> http.StatusBadRequest) >> return >> } >> size = parsedSize >> } >> >> // Generate random data of the specified size >> data := make([]byte, size) >> _, err := rand.Read(data) >> if err != nil { >> http.Error(w, "Could not generate random data", >> http.StatusInternalServerError) >> return >> } >> >> // Base64 encode the random data >> encodedData := base64.StdEncoding.EncodeToString(data) >> >> // Set content type and write the base64 encoded data >> w.Header().Set("Content-Type", "application/base64") >> w.Write([]byte(encodedData)) >> } >> >> func main() { >> port := defaultPort >> >> // Set logging level >> log.SetLevel(log.InfoLevel) >> >> log.SetFormatter(&log.TextFormatter{ >> DisableColors: false, >> FullTimestamp: true, >> }) >> >> // Set up the HTTP server and routes >> http.HandleFunc("/", randomDataHandler) >> >> CERT_FILE := "./certs/server-cert.pem" >> KEY_FILE := "./certs/server-key.pem" >> >> /* Initialize wolfSSL */ >> wolfSSL.WolfSSL_Init() >> >> /* Create WOLFSSL_CTX with tlsv12 */ >> ctx := wolfSSL.WolfSSL_CTX_new(wolfSSL.WolfTLSv1_2_server_method()) >> if ctx == nil { >> fmt.Println(" WolfSSL_CTX_new Failed") >> os.Exit(1) >> } >> >> /* Load server certificates into WOLFSSL_CTX */ >> ret := wolfSSL.WolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, >> wolfSSL.SSL_FILETYPE_PEM) >> if ret != wolfSSL.WOLFSSL_SUCCESS { >> fmt.Println("Error: WolfSSL_CTX_use_certificate Failed") >> os.Exit(1) >> } >> >> /* Load server key into WOLFSSL_CTX */ >> ret = wolfSSL.WolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, >> wolfSSL.SSL_FILETYPE_PEM) >> if ret != wolfSSL.WOLFSSL_SUCCESS { >> fmt.Println("Error: WolfSSL_CTX_use_PrivateKey Failed") >> os.Exit(1) >> } >> >> baseListener, err := net.Listen("tcp", ":"+port) >> if err != nil { >> fmt.Println("Error starting listener:", err) >> return >> } >> defer baseListener.Close() >> >> wolfSSLListener := &wolfSSLListener{ >> listener: baseListener, >> ctx: ctx, >> } >> >> log.Printf("Server listening on https://localhost:%s", port) >> err = http.Serve(wolfSSLListener, nil) >> if err != nil { >> fmt.Println("Error starting HTTP server:", err) >> } >> } >> >> ``` >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com >> <mailto:golang-nuts+unsubscr...@googlegroups.com>. >> To view this discussion visit >> https://groups.google.com/d/msgid/golang-nuts/a662824b-3555-4143-bfd8-b3431b7dc942n%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/a662824b-3555-4143-bfd8-b3431b7dc942n%40googlegroups.com?utm_medium=email&utm_source=footer>. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/1C648B56-431C-4D62-A010-023F21B5830A%40ix.netcom.com.