Skip to content

`closed` field of SnowflakeListener is never initialized

SnowflakeListener is:

https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/blob/e828b0607662c7325f4d1bbf4c5072ce81f38fb9/server/lib/snowflake.go#L165-172

type SnowflakeListener struct {
	addr      net.Addr
	queue     chan net.Conn
	server    *http.Server
	ln        *kcp.Listener
	closed    chan struct{}
	closeOnce sync.Once
}

When it is initialized, its queue channel is initialized but its closed channel is left nil:

	listener := &SnowflakeListener{addr: addr, queue: make(chan net.Conn, 65534)}

The effect of this is that in functions such as SnowflakeListener.queueConn, the select will never take the closed case, because reads from nil channels always block:

https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/blob/e828b0607662c7325f4d1bbf4c5072ce81f38fb9/server/lib/snowflake.go#L273-280

func (l *SnowflakeListener) queueConn(conn net.Conn) error {
	select {
	case <-l.closed:
		return fmt.Errorf("accepted connection on closed listener")
	case l.queue <- conn:
		return nil
	}
}