Hi Gophers,

I have client code which test network transfer performance per second.

For that I use "conn.SetDeadline(time.Second)".
The performance testing is performed in a loop ot 5 rounds where each round 
sets a "SetDeadline" and then d a io.Copy/ZeroReader to the server and 
count the transfered bytes.

This works perfectly with a normal NON-TLS connection to a server. 
After each Timeout because of "SetDeadline" the NON-TLS connection is still 
valid and can be reused.

However, if I do the same with a TLS connection then after the first 
"SetDeadline" and timeout the connection is somehow broken and cannot be 
used anymore for further io.Copy's.

Here is some test code which tests 5 rounds of SetDeadline/ at 1st with a 
standard conneciton and then with TLS connection.
With the TLS connection it breaks and 0 bytes are transfered all the time.

Looking for help :-)

Thanks - Marcel.

package main

import (
        "context"
        "crypto/rand"
        "crypto/tls"
        "encoding/hex"
        "io"
        "io/ioutil"
        "log"
        "net"
        "time"
)

const (
        ciddr    = ":5000"
        keyInHex = 
"2d2d2d2d2d424547494e2050524956415445204b45592d2d2d2d2d0d0a4d494945764149424144414e42676b71686b6947397730424151454641415343424b59776767536941674541416f49424151444f4259315353616b386c7955530d0a384f597252477334314b7456554c647439516e71597169555636465a4e4b764f7a6c56717274506e76355a564d4a5462334d75326a4f2f54694b32366b5647440d0a2f584b61436b564e6b7647687a4e514736467a426a4d67734d72616f5a59472f49523744333663724847344553717251713645326647706c4766716d526643370d0a4c53744f487a364a4f476250715670346c645a546d70335334565857786a73326e4a4d3637576d577061436975566351376a703976576f50325657664659426a0d0a447a49547633574d6f477451466c42614947307934395a68626e32793056414e304c4b6c4775476244386b6543764a66372b65414b5a6a7668746364612b586b0d0a72496d4e51544a4d4f624c2b6e5455305a7771666a4574754c46736336696a306f5278384543584475585a73537731536b784e4c4d494576315843577531434d0d0a31447042626b4b2f41674d4241414543676745414555596e356b6c6b316a363644672b437a5166736b5a524c56566a794f46622b594e6571324e314d477757750d0a6a6957417866516f73"
 +
                
"6c712f43522b4d7136366b716762424b525268744b33776a73655762314944493544356a35357a2f4b7849387257534a78714e6443736d0d0a714e626e464864524e6530705546544f593761775372673931344a4a494e336d5a4674534d5465766236503641746c7053346b4d736d2f5a596441672b5750350d0a422f663177736b69356944684d582f3364773532454830574d5743554e3256414a2f696d316e365732616e6c3054494f4a69774d30336a732b767a61367048650d0a59443347345366702f5a53303573576f2f7846796677384245565673655535736d70545852775379544f484d763178714835584c4f4b367845615173386c42560d0a4b6b77676f794849364c334b6975756d6a45396656667a6a5a686968682f443241616570753262446d514b426751447a2b4e3662476e73693468744f3347394a0d0a36743870776d39475565346f764f367131377132396f726d31426751322f516462674c785641417442336436544939586b566c516f744a58756562537a3674510d0a66763971674d6c6b5a6552413965367a49416668553457526b5270557448584c3047476875583546696954363532316b456f657833726b6747417437593353670d0a2b314749645a3474774252616b536434474b7556775a514d41774b42675144594c626464797735455553486178596c"
 +
                
"5275593874477945616f726a564e4e4c440d0a6d5030374748726a6c343970697a4e54775a493770666833466c4f36504a3544664d6b4c7231487853416f394151376f44585470506e716457433637544279670d0a50387a325544434164786d442b4d4872766b2f7070536c356a5944394f3839777133417166326b7767634f35554150484a47367a304a4f45366477482b4f48350d0a79437747684755586c514b426748516a767553624949386b6a39646b7646323176334b447172455241347a46452b436b5062416e6755774e487a2b33565768460d0a48495742645776364a2f684352654a72774e6251433833544933797265325167634c706b674871597671586c375447385238514f484947465438474f2f7078390d0a6f4678366a772f506958636667455770524974352b5371384234732f64782f44513762774e744b556f35765269625a3047417038556c7539416f4741427554650d0a5669566c6e525168536b4c47634537456e43476a5771415a324f4c495865694247754e61392b736262626738754d305268736c794e516f4850596331584e32620d0a343732426c58704171565668546c4576693069737a4676466b622b4a6f69716d744b77312f384c4d6b344c5a5846564459795962506e3865762f537156754f410d0a766a6f313970414d31396f505a4d6871703131"
 +
                
"646476326d514c4c564d67774b4b324d4a666b6b43675942504243304b6579624736444964356d5a4a7056394b0d0a4238575a5663727945447a786f75486473517145686637666c355a7532467a38326b656d41686a616b3531554546525437674e596b4b414753673877507453610d0a75614c2f2b4c626174504d2b5a6c716a51417859354f3454392b4e56305875546d4644744f4c366765493054665374306a6179754e654b6c68374c63516c6e510d0a6270495853574c2b707850655a6858774e2b316972773d3d0d0a2d2d2d2d2d454e442050524956415445204b45592d2d2d2d2d0d0a"
        pemInHex = 
"2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0d0a4d4949432f6a434341656167417749424167494a414d774c783261574f386a414d413047435371475349623344514542437755414d425178456a415142674e560d0a42414d4d43577876593246736147397a64444165467730794d4441784d5451784d4441784d5442614677307a4d4441784d5445784d4441784d5442614d4251780d0a456a415142674e5642414d4d43577876593246736147397a64444343415349774451594a4b6f5a496876634e4151454242514144676745504144434341516f430d0a67674542414d34466a564a4a715479584a524c7735697445617a6a55713156517432333143657069714a52586f566b307138374f56577175302b652f6c6c55770d0a6c4e76637937614d37394f49726271525559503963706f4b525532533861484d3141626f584d474d794377797471686c6762386848735066707973636267524b0d0a717443726f545a38616d555a2b715a46384c73744b303466506f6b345a732b70576e6956316c4f616e644c68566462474f7a61636b7a7274615a616c6f4b4b350d0a567844754f6e323961672f5a565a385667474d504d684f2f645979676131415755466f6762544c6a316d467566624c525541335173715561345a73507952344b0d0a386c2f76353441706d"
 +
                
"4f2b473178317235655373695931424d6b7735737636644e54526e43702b4d5332347357787a714b505368484877514a634f35646d784c0d0a44564b544530737767532f56634a613755497a554f6b4675517238434177454141614e544d464577485159445652304f424259454641315370783369486e394e0d0a66557463655343494f55376d334c71664d42384741315564497751594d4261414641315370783369486e394e66557463655343494f55376d334c71664d4138470d0a41315564457745422f7751464d414d42416638774451594a4b6f5a496876634e4151454c4251414467674542414445786864464a724a6469576d3551303067710d0a74706876754869634664315864516b613851764a6e323736354e706a624d776b4f67494f706d32644d376e467063784d4a5a77546875317062515864653071570d0a4f415979593274654b7344507a302b48496c755a49737336697a5852732f2b4a43312b2b6a4a34673746316d64556a64517a7733506957316b72516d2f5746430d0a624d34544c656f3158464b4c42696678674170346f532f317a37674478545962336f764c7a415243637857345571726a384b7036467474616c78326c4c3566470d0a6f307a452b4358746d4756636546316e427050685737366430614435487a56316931497055384b6f5674344a673043"
 +
                
"524176714139556835673279434d3531550d0a5762766a564934526b474c4a6d5761796d4269572b52526f3465766c347679353650356744526b766574464e3443444e41327a412f71307762653654516759350d0a5479493d0d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0d0a"
)

type ZeroReader struct {
}

func NewZeroReader() *ZeroReader {
        return &ZeroReader{}
}

func (this ZeroReader) Read(p []byte) (n int, err error) {
        for i := range p {
                p[i] = 0
        }

        return len(p), nil
}

func hexToBuffer(txt string) ([]byte, error) {
        ba, err := hex.DecodeString(txt)
        if err != nil {
                log.Println(err)
                return nil, err
        }

        return ba, nil
}

func newTlsConfig() (*tls.Config, error) {
        key, err := hexToBuffer(keyInHex)
        if err != nil {
                log.Println(err)
                return nil, err
        }

        pem, err := hexToBuffer(pemInHex)
        if err != nil {
                log.Println(err)
                return nil, err
        }

        certificate, err := tls.X509KeyPair(pem, key)
        if err != nil {
                log.Println(err)
                return nil, err
        }

        tlsConfig := &tls.Config{Certificates: []tls.Certificate{certificate}}
        tlsConfig.Rand = rand.Reader

        return tlsConfig, nil
}

func NewServer(ctx context.Context, useTls bool) error {
        var conn net.Conn

        if useTls {
                tlsConfig, err := newTlsConfig()

                log.Printf("TLS server: listen")
                ln, err := tls.Listen("tcp", ciddr, tlsConfig)
                if err != nil {
                        log.Println(err)
                        return err
                }
                defer func() {
                        err := ln.Close()
                        if err != nil {
                                log.Println(err)
                        }
                }()

                log.Printf("TLS server: listen accept ...")
                conn, err = ln.Accept()
                if err != nil {
                        log.Println(err)
                        return err
                }
        } else {
                log.Printf("server: listen")
                ln, err := net.Listen("tcp", ciddr)
                if err != nil {
                        log.Println(err)
                        return err
                }
                defer func() {
                        err := ln.Close()
                        if err != nil {
                                log.Println(err)
                        }
                }()

                log.Printf("server: listen accept ...")
                conn, err = ln.Accept()
                if err != nil {
                        log.Println(err)
                        return err
                }
        }

        select {
        case <-ctx.Done():
                err := conn.Close()
                if err != nil {
                        log.Println(err)
                        return err
                }
        default:
                log.Printf("server read and discard ...")

                n,err := io.Copy(ioutil.Discard, conn)
                if n > 0 {
                        log.Printf("server bytes read: %d",n)

                }
                if err != nil {
                        log.Println(err)
                        return err
                }
        }

        return nil
}

func main() {
        useTls := false

        for {
                log.Printf("--------------------------------")
                log.Printf("Test with TLS = %v",useTls)

                ctx,cancel := context.WithCancel(context.Background())

                go func() {
                        err := NewServer(ctx,useTls)
                        if err != nil {
                                log.Println(err)
                                panic(err)
                        }
                }()

                log.Printf("Give server time to startup ...")
                time.Sleep(time.Second)

                var conn net.Conn

                if useTls {
                        var err error

                        config := &tls.Config{
                                InsecureSkipVerify: true,
                        }

                        log.Printf("Dial TLS to server ... ")

                        conn, err = tls.Dial("tcp", ciddr, config)
                        if err != nil {
                                log.Println(err)
                                panic(err)
                        }
                } else {
                        var err error

                        log.Printf("Dial to server ... ")

                        conn,err = net.Dial("tcp",ciddr)
                        if err != nil {
                                log.Println(err)
                                panic(err)
                        }
                }

                log.Printf("Connection established")

                for i := 0; i < 5; i++ {
                        log.Printf("loop %v: setDeadline",i)
                        conn.SetDeadline(time.Now().Add(time.Second))

                        n,err := io.Copy(conn,ZeroReader{})
                        log.Printf("loop %v: bytes written: %d",i,n)
                        if err != nil {
                                neterr, ok := err.(net.Error)

                                if !ok || neterr.Timeout() {
                                        continue
                                }
                                log.Println(err)
                                panic(err)
                        }

                }

                log.Printf("Connection close")
                err := conn.Close()
                if err != nil {
                        log.Println(err)
                        panic(err)
                }

                log.Printf("Kill server")
                cancel()
                log.Printf("Give server time to die ...")
                time.Sleep(time.Second)

                log.Printf("Server killed")

                useTls = !useTls
        }
}



My env:

set GO111MODULE=on
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\ogmpetav\AppData\Local\go-build
set GOENV=C:\Users\ogmpetav\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\xxx\Documents\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=D:\go\src\deadline\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments 
-fmessage-length=0 
-fdebug-prefix-map=C:\Users\xxx\AppData\Local\Temp\go-build505968610=/tmp/go-build
 
-gno-record-gcc-switches



-- 
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 on the web visit 
https://groups.google.com/d/msgid/golang-nuts/0eff362a-854d-4269-b48b-c988d1c34897%40googlegroups.com.

Reply via email to