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

Error: "connection already exists" in AddConn Method of 'connMultiplexer' #155

Open
minchopm opened this issue Jun 14, 2024 · 1 comment

Comments

@minchopm
Copy link

Description:

I encountered a panic error stating "connection already exists" while using webtransport-go. The error occurs in the AddConn method of the connMultiplexer struct within the quic-go package. Below is a detailed explanation of the problem along with the relevant code snippets.

Code Implementation:
Server:

func ServerWT(conn net.PacketConn) {
	tlsConfig, _ := generateTLSConfig3("<server addr>")
	s := webtransport.Server{
		H3: http3.Server{
			Addr:      ":9000",
			TLSConfig: tlsConfig,
			QUICConfig: &quic.Config{
				EnableDatagrams:       true,
				MaxIdleTimeout:        60 * time.Second,
				KeepAlivePeriod:       15 * time.Second,
				MaxIncomingStreams:    1000,
				MaxIncomingUniStreams: 1000,
			},
		},
		ReorderingTimeout: time.Duration(100 * time.Second),
	}

	http.HandleFunc("/webtransport", func(w http.ResponseWriter, r *http.Request) {

		fmt.Println("Connection:", r)
		_, err := s.Upgrade(w, r)
		if err != nil {
			fmt.Println("Upgrading failed: ", err)
			w.WriteHeader(500)
			return
		}

	})
	fmt.Println("WT server serving")
	err := s.Serve(conn)
	if err != nil {
		fmt.Println("Failed to start server:", err)
	}
}

Client:

func WtClient(udpClient net.PacketConn, addr string) {
	go SendDataClientWT()
	blockUpgrade := make(chan struct{})
	d := webtransport.Dialer{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
		QUICConfig: &quic.Config{
			EnableDatagrams:       true,
			MaxIdleTimeout:        60 * time.Second,
			KeepAlivePeriod:       15 * time.Second,
			MaxIncomingStreams:    1000,
			MaxIncomingUniStreams: 1000,
		},
		DialAddr: func(ctx context.Context, addr string, tlsConf *tls.Config, conf *quic.Config) (quic.EarlyConnection, error) {
			udpAddr, err := net.ResolveUDPAddr("udp4", addr)
			if err != nil {
				fmt.Println("ResolveUDPAddr error:", err)
				return nil, err
			}
			conn, err := quic.DialEarly(ctx, udpClient, udpAddr, tlsConf, conf)
			if err != nil {
				fmt.Println("DialEarly err: ", err)
				return nil, err
			}
			return &requestStreamDelayingConn{done: blockUpgrade, EarlyConnection: conn}, nil
		},
	}

	headers := http.Header{}
	rsp, conn, err := d.Dial(context.Background(), "https://"+addr+"/webtransport", headers)
	if err != nil {
		fmt.Println("Dial err: ", err)
		return
	}
	sessionWT = conn
	go StartAudioRecording()
	fmt.Println("Connection established: ", conn)
	fmt.Println("Response: ", rsp)
	fmt.Println("Enter messages to send, type 'exit' to quit:")
}

main:

func main() {
	addr := net.UDPAddr{
		Port: 3344,
		IP:   net.ParseIP("0.0.0.0"),
	}
	conn, _ := net.ListenUDP("udp", &addr)
	// Set UDP socket options
	go ServerWT(conn)
	WtClient(conn, "localhost:3344")
}

Error:

panic: connection already exists

goroutine 3 [running]:
github.com/quic-go/quic-go.(*connMultiplexer).AddConn(0x140000a61a0, {0x1038da998?, 0x1400005a040?})
        ../go/pkg/mod/github.com/quic-go/[email protected]/multiplexer.go:59 +0x198
...

Problematic Code:

func (m *connMultiplexer) AddConn(c indexableConn) {
    m.mutex.Lock()
    defer m.mutex.Unlock()

    connIndex := m.index(c.LocalAddr())
    p, ok := m.conns[connIndex]
    if ok {
        panic("connection already exists")
    }
    m.conns[connIndex] = p
}

Details:

I am attempting to establish a WebTransport server and client using the webtransport-go library.
The server initializes and listens for connections using the QUIC protocol.
Upon establishing a connection, the server attempts to add the connection to the multiplexer, resulting in a panic indicating that the connection already exists.
Steps to Reproduce:

Run the provided code.
Observe the panic error with the message "connection already exists".
Expected Behavior:
The server should establish connections without encountering a panic, handling multiple connections appropriately.

Request:

Please provide guidance on resolving this issue.
If this is a known issue, suggest any workarounds or fixes.
Update the documentation if necessary to reflect any changes or known limitations.
Thank you for your assistance.

@marten-seemann
Copy link
Member

I will not be able to investigate this. Please see the README for details on the funding situation of the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants