github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/packet_number_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  	"io"
    17  	"log"
    18  	"math/big"
    19  	"os"
    20  
    21  	"github.com/danielpfeifer02/quic-go-prio-packs"
    22  	"github.com/danielpfeifer02/quic-go-prio-packs/crypto_turnoff"
    23  	"github.com/danielpfeifer02/quic-go-prio-packs/packet_setting"
    24  	"github.com/danielpfeifer02/quic-go-prio-packs/priority_setting"
    25  	"github.com/danielpfeifer02/quic-go-prio-packs/qlog"
    26  )
    27  
    28  const addr = "localhost:4242"
    29  
    30  const message = "foobar"
    31  
    32  const NUM_MESSAGES = 3
    33  
    34  var counter int = 0
    35  var liste = make([]int, 0)
    36  
    37  // We start a server echoing data on the first stream the client opens,
    38  // then connect with a client, send the message, and wait for its receipt.
    39  func main() {
    40  
    41  	os.Remove("tls.keylog")
    42  
    43  	go func() { log.Fatal(echoServer()) }()
    44  
    45  	err := clientMain()
    46  	if err != nil {
    47  		panic(err)
    48  	}
    49  }
    50  
    51  // Start a server that echos all data on the first stream opened by the client
    52  func echoServer() error {
    53  
    54  	crypto_turnoff.CRYPTO_TURNED_OFF = false
    55  	packet_setting.ALLOW_SETTING_PN = true
    56  	packet_setting.ConnectionInitiationBPFHandler = initiationBPFHandler
    57  	packet_setting.ConnectionRetirementBPFHandler = retirementBPFHandler
    58  	packet_setting.PacketNumberIncrementBPFHandler = packetNumberBPFHanlder
    59  	packet_setting.ConnectionUpdateBPFHandler = updateBPFHandler
    60  	packet_setting.AckTranslationBPFHandler = ackHandler
    61  	packet_setting.PRINT_PACKET_RECEIVING_INFO = true
    62  
    63  	listener, err := quic.ListenAddr(addr, generateTLSConfig(), generateQUICConfig())
    64  	if err != nil {
    65  		panic(err)
    66  	}
    67  	defer listener.Close()
    68  
    69  	// Accept the incoming connection from the client
    70  	conn, err := listener.Accept(context.Background())
    71  	if err != nil {
    72  		panic(err)
    73  	}
    74  
    75  	stream, err := conn.AcceptStream(context.Background())
    76  	if err != nil {
    77  		panic(err)
    78  	}
    79  	defer stream.Close()
    80  
    81  	pn_multiplier := 0x42
    82  
    83  	for i := 1; i <= NUM_MESSAGES; i++ {
    84  
    85  		buf := make([]byte, len(message)+1)
    86  
    87  		_, err = io.ReadFull(stream, buf)
    88  		if err != nil {
    89  			panic(err)
    90  		}
    91  
    92  		fmt.Printf("	>>Server: Got '%s'\n	>>Server: Echoing on same stream\n", string(buf))
    93  		_, err = stream.Write(buf)
    94  		if err != nil {
    95  			panic(err)
    96  		}
    97  
    98  		conn.SetPacketNumber(int64(i * pn_multiplier))
    99  		conn.SetHighestSent(int64(i * pn_multiplier))
   100  
   101  	}
   102  
   103  	connid := conn.GetDestConnID(stream)
   104  	fmt.Println("Connection ID: ", connid.String())
   105  
   106  	return nil
   107  }
   108  
   109  func ackHandler(pn int64, conn packet_setting.QuicConnection) (int64, error) {
   110  	fmt.Println("Packet Number changed to", pn, "by (", conn.(quic.Connection).RemoteAddr().String(), ",", conn.(quic.Connection).LocalAddr().String(), ")")
   111  	return pn, nil
   112  }
   113  
   114  func updateBPFHandler(id []byte, l uint8, conn packet_setting.QuicConnection) {
   115  	fmt.Println("Update BPF Handler called")
   116  }
   117  
   118  func initiationBPFHandler(id []byte, l uint8, conn packet_setting.QuicConnection) {
   119  	qconn := conn.(quic.Connection)
   120  	fmt.Println("create id with length: ", len(id), "from", qconn.RemoteAddr().String())
   121  
   122  	// fmt.Println("Initiation BPF Handler called")
   123  	// liste = append(liste, counter)
   124  	// fmt.Printf("Adding %d to the list\n", counter)
   125  	// counter++
   126  }
   127  
   128  func retirementBPFHandler(id []byte, l uint8, conn packet_setting.QuicConnection) {
   129  	qconn := conn.(quic.Connection)
   130  	fmt.Println("retire id with length: ", len(id), "from", qconn.RemoteAddr().String())
   131  	// fmt.Println("Retirement BPF Handler called")
   132  	// fmt.Printf("Removing %d from the list\n", liste[0])
   133  	// liste = liste[1:]
   134  }
   135  
   136  func packetNumberBPFHanlder(pn int64, conn packet_setting.QuicConnection) {
   137  	// TODO: pn 0 seems to be used multiple times in the beginning?
   138  	fmt.Println("Packet Number changed to", pn, "by (", conn.(quic.Connection).RemoteAddr().String(), ",", conn.(quic.Connection).LocalAddr().String(), ")")
   139  }
   140  
   141  func clientMain() error {
   142  	tlsConf := &tls.Config{
   143  		InsecureSkipVerify: true,
   144  		NextProtos:         []string{"quic-echo-example"},
   145  	}
   146  	conn, err := quic.DialAddr(context.Background(), addr, tlsConf, generateQUICConfig())
   147  	if err != nil {
   148  		return err
   149  	}
   150  	defer conn.CloseWithError(0, "")
   151  
   152  	// Open a new stream
   153  	stream_prio, err := conn.OpenStreamSyncWithPriority(context.Background(), priority_setting.HighPriority)
   154  	if err != nil {
   155  		return err
   156  	}
   157  	defer stream_prio.Close()
   158  
   159  	for i := 1; i <= NUM_MESSAGES; i++ {
   160  
   161  		fmt.Printf("	>>Client: Sending '%s%d'\n", message, i)
   162  		_, err = stream_prio.Write([]byte(message + fmt.Sprintf("%d", i)))
   163  		if err != nil {
   164  			return err
   165  		}
   166  
   167  		buf := make([]byte, len(message)+1)
   168  		_, err = io.ReadFull(stream_prio, buf)
   169  		if err != nil {
   170  			return err
   171  		}
   172  		fmt.Printf("	>>Client: Got '%s'\n\n", buf)
   173  
   174  	}
   175  
   176  	return nil
   177  }
   178  
   179  // A wrapper for io.Writer that also logs the message.
   180  type loggingWriter struct{ io.Writer }
   181  
   182  func (w loggingWriter) Write(b []byte) (int, error) {
   183  	fmt.Printf("	>>Server: Got '%s'\n	>>Server: Echoing on same stream\n", string(b))
   184  	return w.Writer.Write(b)
   185  }
   186  
   187  // Setup a bare-bones TLS config for the server
   188  func generateTLSConfig() *tls.Config {
   189  	key, err := rsa.GenerateKey(rand.Reader, 1024)
   190  	if err != nil {
   191  		panic(err)
   192  	}
   193  	template := x509.Certificate{SerialNumber: big.NewInt(1)}
   194  	certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
   195  	if err != nil {
   196  		panic(err)
   197  	}
   198  	keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
   199  	certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
   200  
   201  	tlsCert, err := tls.X509KeyPair(certPEM, keyPEM)
   202  	if err != nil {
   203  		panic(err)
   204  	}
   205  
   206  	// Create a KeyLogWriter
   207  	keyLogFile, err := os.OpenFile("tls.keylog", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
   208  	if err != nil {
   209  		panic(err)
   210  	}
   211  	// defer keyLogFile.Close() // TODO why not close?
   212  
   213  	return &tls.Config{
   214  		Certificates: []tls.Certificate{tlsCert},
   215  		NextProtos:   []string{"quic-echo-example"},
   216  		KeyLogWriter: keyLogFile,
   217  		CipherSuites: []uint16{tls.TLS_CHACHA20_POLY1305_SHA256},
   218  	}
   219  }
   220  
   221  func generateQUICConfig() *quic.Config {
   222  	return &quic.Config{
   223  		Tracer: qlog.DefaultTracer,
   224  	}
   225  }