github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/datagram_example/example.go (about) 1 package main 2 3 // https://fossies.org/linux/quic-go/example/echo/echo.go 4 // if error: 5 // sudo sysctl -w net.core.rmem_max=2500000 6 // sudo sysctl -w net.core.wmem_max=2500000 7 8 import ( 9 "context" 10 "crypto/rand" 11 "crypto/rsa" 12 "crypto/tls" 13 "crypto/x509" 14 "encoding/pem" 15 "fmt" 16 "math/big" 17 "os" 18 "time" 19 20 "github.com/danielpfeifer02/quic-go-prio-packs" 21 "github.com/danielpfeifer02/quic-go-prio-packs/crypto_turnoff" 22 "github.com/danielpfeifer02/quic-go-prio-packs/priority_setting" 23 "github.com/danielpfeifer02/quic-go-prio-packs/qlog" 24 ) 25 26 const server_addr = "192.168.11.2:4242" 27 28 const message = "foobar" 29 30 const NUM_MESSAGES = 3 31 32 var PRIO = priority_setting.NoPriority 33 var PRIO_S = priority_setting.HighPriority 34 var PRIO_C = priority_setting.LowPriority 35 36 // We start a server echoing data on the first stream the client opens, 37 // then connect with a client, send the message, and wait for its receipt. 38 func main() { 39 40 // expect one argument: "server" or "client" 41 if len(os.Args) != 2 { 42 fmt.Println("Usage: go run example.go server|client") 43 return 44 } 45 46 is_server := os.Args[1] == "server" 47 is_client := os.Args[1] == "client" 48 49 os.Remove("tls.keylog") 50 crypto_turnoff.CRYPTO_TURNED_OFF = true 51 52 if is_server { 53 err := echoServer() 54 if err != nil { 55 panic(err) 56 } 57 } else if is_client { 58 err := clientMain() 59 if err != nil { 60 panic(err) 61 } 62 } else { 63 fmt.Println("Usage: go run example.go server|client") 64 } 65 66 time.Sleep(100 * time.Millisecond) 67 } 68 69 // Start a server that echos all data on the first stream opened by the client 70 func echoServer() error { 71 72 listener, err := quic.ListenAddr(server_addr, generateTLSConfig(), generateQUICConfig()) 73 if err != nil { 74 panic(err) 75 } 76 defer listener.Close() 77 78 // Accept the incoming connection from the client 79 conn, err := listener.Accept(context.Background()) 80 if err != nil { 81 panic(err) 82 } 83 84 for i := 1; i <= NUM_MESSAGES; i++ { 85 86 data, err := conn.ReceiveDatagram(context.Background()) 87 if err != nil { 88 return err 89 } 90 fmt.Printf(" >>Server: Got '%s'\n", string(data)) 91 err = conn.SendDatagramWithPriority([]byte(data), PRIO_S) 92 // err = conn.SendDatagram([]byte(data)) 93 if err != nil { 94 return err 95 } 96 97 } 98 99 time.Sleep(100 * time.Millisecond) 100 101 return nil 102 } 103 104 func clientMain() error { 105 tlsConf := &tls.Config{ 106 InsecureSkipVerify: true, 107 NextProtos: []string{"quic-echo-example"}, 108 } 109 conn, err := quic.DialAddr(context.Background(), server_addr, tlsConf, generateQUICConfig()) 110 if err != nil { 111 return err 112 } 113 defer conn.CloseWithError(0, "") 114 115 // Open a new stream 116 // stream_prio, err := conn.OpenStreamSyncWithPriority(context.Background(), priority_setting.HighPriority) 117 // if err != nil { 118 // return err 119 // } 120 // defer stream_prio.Close() 121 122 for i := 1; i <= NUM_MESSAGES; i++ { 123 124 fmt.Printf(" >>Client: Sending '%s%d'\n", message, i) 125 126 err := conn.SendDatagramWithPriority([]byte(message+fmt.Sprintf("%d", i)), PRIO_C) 127 // err := conn.SendDatagram([]byte(message + fmt.Sprintf("%d", i))) 128 if err != nil { 129 return err 130 } 131 buf, err := conn.ReceiveDatagram(context.Background()) 132 if err != nil { 133 return err 134 } 135 fmt.Printf(" >>Client: Got '%s'\n\n", buf) 136 137 } 138 139 time.Sleep(100 * time.Millisecond) 140 141 return nil 142 } 143 144 // Setup a bare-bones TLS config for the server 145 func generateTLSConfig() *tls.Config { 146 key, err := rsa.GenerateKey(rand.Reader, 1024) 147 if err != nil { 148 panic(err) 149 } 150 template := x509.Certificate{SerialNumber: big.NewInt(1)} 151 certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key) 152 if err != nil { 153 panic(err) 154 } 155 keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)}) 156 certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) 157 158 tlsCert, err := tls.X509KeyPair(certPEM, keyPEM) 159 if err != nil { 160 panic(err) 161 } 162 163 // Create a KeyLogWriter 164 keyLogFile, err := os.OpenFile("tls.keylog", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 165 if err != nil { 166 panic(err) 167 } 168 // defer keyLogFile.Close() // TODO why not close? 169 170 return &tls.Config{ 171 Certificates: []tls.Certificate{tlsCert}, 172 NextProtos: []string{"quic-echo-example"}, 173 KeyLogWriter: keyLogFile, 174 CipherSuites: []uint16{tls.TLS_CHACHA20_POLY1305_SHA256}, 175 } 176 } 177 178 func generateQUICConfig() *quic.Config { 179 return &quic.Config{ 180 Tracer: qlog.DefaultTracer, 181 EnableDatagrams: true, 182 } 183 }