@@ -84,7 +84,7 @@ func (c *ConnMux) Serve() error {
8484 for {
8585 conn , err := c .root .Accept ()
8686 if err != nil {
87- c .lg .Error ("connection error" , zap .Error (err ))
87+ c .lg .Error ("connection accept error" , zap .Error (err ))
8888 return c .Close ()
8989 }
9090 go c .serve (conn )
@@ -96,17 +96,18 @@ func (c *ConnMux) serve(conn net.Conn) {
9696 conn .SetDeadline (time .Now ().Add (readDeadlineTimeout ))
9797 defer conn .SetReadDeadline (time.Time {})
9898
99- buf := make ([]byte , 1024 )
99+ buf := make ([]byte , 512 )
100100 buffConn := newBufferedConn (conn )
101101 // Check if is TLS or plain TCP
102- _ , err := buffConn .sniffReader ().Read (buf )
102+ n , err := buffConn .sniffReader ().Read (buf )
103103 if err != nil && err != io .EOF {
104104 // exit since it will panic trying to detect if is TLS
105105 c .lg .Error ("error reading from the connection" , zap .Error (err ))
106106 conn .Close ()
107107 return
108108 }
109- c .lg .Debug ("connection received" , zap .String ("remote address" , conn .RemoteAddr ().String ()), zap .Int ("buffer size" , len (buf )), zap .String ("buffer content" , string (buf [0 :])))
109+ r := bytes .NewReader (buf [:n ])
110+ c .lg .Debug ("connection received" , zap .String ("remote address" , conn .RemoteAddr ().String ()), zap .Int ("read size" , n ), zap .String ("buffer content" , string (buf [:n ])))
110111 // Check if is TLS or plain TCP
111112 isTLS := buf [0 ] == 0x16
112113 if isTLS {
@@ -133,7 +134,7 @@ func (c *ConnMux) serve(conn net.Conn) {
133134 conn .Close ()
134135 return
135136 }
136- isGRPC := isGRPCConnection (c .lg , buffConn , io .MultiReader (bytes . NewReader ( buf ) , buffConn .sniffReader ()))
137+ isGRPC := isGRPCConnection (c .lg , buffConn , io .MultiReader (r , buffConn .sniffReader ()))
137138 c .forward (isGRPC , buffConn )
138139 }
139140
@@ -152,7 +153,7 @@ func (c *ConnMux) forward(isGRPC bool, conn net.Conn) {
152153 return
153154 }
154155
155- if c .grpc != nil {
156+ if isGRPC && c .grpc != nil {
156157 c .lg .Debug ("forwarding connection to the GRPC backend" , zap .String ("remote address" , conn .RemoteAddr ().String ()))
157158 select {
158159 case c .grpc .connc <- conn :
@@ -227,6 +228,7 @@ func (c *ConnMux) GRPCListener() net.Listener {
227228// bufferedConn allows to peek in the buffer of the connection
228229// without advancing the reader.
229230type bufferedConn struct {
231+ mu sync.Mutex
230232 net.Conn
231233 buf * bytes.Buffer
232234}
@@ -239,61 +241,83 @@ var bufferPool = sync.Pool{
239241 },
240242}
241243
242- func newBufferedConn (c net.Conn ) bufferedConn {
243- return bufferedConn {
244+ func newBufferedConn (c net.Conn ) * bufferedConn {
245+ return & bufferedConn {
244246 Conn : c ,
245247 buf : bufferPool .Get ().(* bytes.Buffer ),
246248 }
247249}
248250
249- func (b bufferedConn ) Read (p []byte ) (int , error ) {
250- if b .buf .Len () > 0 {
251- n , err := b .buf .Read (p )
252- if err == io .EOF {
253- // Don't return EOF yet. More readers remain.
254- return n , nil
255- }
256- return n , err
257- }
258- // return the buffer to the pool
259- b .buf .Reset ()
260- bufferPool .Put (b .buf )
261- return b .Conn .Read (p )
251+ func (b * bufferedConn ) Read (p []byte ) (int , error ) {
252+ b .mu .Lock ()
253+ defer b .mu .Unlock ()
254+ return io .MultiReader (b .buf , b .Conn ).Read (p )
262255}
263256
264- func (b bufferedConn ) Close () error {
265- // In case we didn't have time to return the buffer to the pool
266- if b .buf != nil {
267- // return the buffer to the pool
257+ func (b * bufferedConn ) Close () error {
258+ // return the buffer to the pool
259+ defer func () {
260+ b .mu .Lock ()
261+ defer b .mu .Unlock ()
268262 b .buf .Reset ()
269263 bufferPool .Put (b .buf )
270- }
264+ }()
271265 return b .Conn .Close ()
272266}
273267
274- func (b bufferedConn ) sniffReader () io.Reader {
268+ func (b * bufferedConn ) sniffReader () io.Reader {
275269 return io .TeeReader (b .Conn , b .buf )
276270}
277271
278272func isGRPCConnection (lg * zap.Logger , w io.Writer , r io.Reader ) bool {
279273 // check the http2 client preface
280- buf := make ([]byte , len ( http2 . ClientPreface ) )
274+ buf := make ([]byte , 512 )
281275 n , err := r .Read (buf )
282- if err != nil || n != len (http2 .ClientPreface ) {
276+ if err != nil || n < len (http2 .ClientPreface ) {
283277 return false
284278 }
285279
286- if ! bytes .Equal (buf , []byte (http2 .ClientPreface )) {
280+ if ! bytes .Equal (buf [: len ( http2 . ClientPreface )] , []byte (http2 .ClientPreface )) {
287281 lg .Debug ("not found http2 client preface" , zap .String ("preface" , string (buf )))
288282 return false
289283 }
290- lg .Debug ("found http2 client preface" )
284+ lg .Debug ("found http2 client preface" , zap .Int ("bytes read" , n ))
285+
286+ reader := r
287+ if n > 33 {
288+ reader = io .MultiReader (bytes .NewReader (buf [len (http2 .ClientPreface ):]), r )
289+ }
290+ framer := http2 .NewFramer (w , reader )
291+ // GRPC blocks until receive the Settings frame
292+ // This means we should have the preface 24 + setting frame 9
293+ // HTTP2 fails if we write it before forwarding
294+ if n <= 33 {
295+ lg .Debug ("write http2 settings" )
296+ err = framer .WriteSettings ()
297+ if err != nil {
298+ lg .Debug ("error sending setting frame" , zap .Error (err ))
299+ return false
300+ }
301+ }
302+ // The server connection preface consists of a potentially empty
303+ // SETTINGS frame (Section 6.5) that MUST be the first frame the server
304+ // sends in the HTTP/2 connection.
305+ f , err := framer .ReadFrame ()
306+ if err != nil {
307+ lg .Debug ("error reading frame" , zap .Error (err ))
308+ return false
309+ }
310+ // The SETTINGS frames received from a peer as part of the connection
311+ // preface MUST be acknowledged (see Section 6.5.3) after sending the
312+ // connection preface.
313+ if _ , ok := f .(* http2.SettingsFrame ); ! ok {
314+ lg .Debug ("expected setting frame" )
315+ }
291316
292317 // identify GRPC connections matching match headers names or values defined
293318 // on https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
294319 done := false
295320 isGRPC := false
296- framer := http2 .NewFramer (w , r )
297321 // use the default value for the maxDynamixTable size
298322 // https://pkg.go.dev/golang.org/x/net/http2
299323 // "If zero, the default value of 4096 is used."
@@ -306,12 +330,8 @@ func isGRPCConnection(lg *zap.Logger, w io.Writer, r io.Reader) bool {
306330 }
307331 done = true
308332 })
309- err = framer .WriteSettingsAck ()
310- if err != nil {
311- lg .Debug ("error acking setting frame" , zap .Error (err ))
312- return false
313- }
314- lg .Debug ("ack settings" )
333+
334+ lg .Debug ("reading frames" )
315335 for ! done {
316336 f , err := framer .ReadFrame ()
317337 if err != nil {
@@ -323,10 +343,16 @@ func isGRPCConnection(lg *zap.Logger, w io.Writer, r io.Reader) bool {
323343 // preface MUST be acknowledged (see Section 6.5.3) after sending the
324344 // connection preface.
325345 case * http2.SettingsFrame :
326- lg .Debug ("found setting frame" )
327346 if f .IsAck () {
347+ lg .Debug ("found setting ACK frame" )
328348 continue
329349 }
350+ lg .Debug ("found setting frame" )
351+ err := framer .WriteSettingsAck ()
352+ if err != nil {
353+ lg .Debug ("error writing settings frame" , zap .Error (err ))
354+ return false
355+ }
330356
331357 case * http2.HeadersFrame :
332358 hdec .Write (f .HeaderBlockFragment ())
0 commit comments