mirror of https://github.com/XTLS/Xray-core
				
				
				
			Fix serverside TLS support of SplitHTTP H1/H2 (#3567)
Fix #3566 Also update testsuite so that all tests read and write some data. Opening a connection is not enough to trigger connection errors, because the connection is so lazy.pull/3581/head
							parent
							
								
									964859b4bc
								
							
						
					
					
						commit
						529f206d33
					
				| 
						 | 
				
			
			@ -269,7 +269,6 @@ func ListenSH(ctx context.Context, address net.Address, port net.Port, streamSet
 | 
			
		|||
	tlsConfig := getTLSConfig(streamSettings)
 | 
			
		||||
	l.isH3 = len(tlsConfig.NextProtos) == 1 && tlsConfig.NextProtos[0] == "h3"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if port == net.Port(0) { // unix
 | 
			
		||||
		listener, err = internet.ListenSystem(ctx, &net.UnixAddr{
 | 
			
		||||
			Name: address.Domain(),
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +286,7 @@ func ListenSH(ctx context.Context, address net.Address, port net.Port, streamSet
 | 
			
		|||
		if err != nil {
 | 
			
		||||
			return nil, errors.New("failed to listen UDP(for SH3) on ", address, ":", port).Base(err)
 | 
			
		||||
		}
 | 
			
		||||
		h3listener, err := quic.ListenEarly(Conn,tlsConfig, nil)
 | 
			
		||||
		h3listener, err := quic.ListenEarly(Conn, tlsConfig, nil)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, errors.New("failed to listen QUIC(for SH3) on ", address, ":", port).Base(err)
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -314,7 +313,6 @@ func ListenSH(ctx context.Context, address net.Address, port net.Port, streamSet
 | 
			
		|||
		if err != nil {
 | 
			
		||||
			return nil, errors.New("failed to listen TCP(for SH) on ", address, ":", port).Base(err)
 | 
			
		||||
		}
 | 
			
		||||
		l.listener = listener
 | 
			
		||||
		errors.LogInfo(ctx, "listening TCP(for SH) on ", address, ":", port)
 | 
			
		||||
 | 
			
		||||
		// h2cHandler can handle both plaintext HTTP/1.1 and h2c
 | 
			
		||||
| 
						 | 
				
			
			@ -324,18 +322,24 @@ func ListenSH(ctx context.Context, address net.Address, port net.Port, streamSet
 | 
			
		|||
			ReadHeaderTimeout: time.Second * 4,
 | 
			
		||||
			MaxHeaderBytes:    8192,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// tcp/unix (h1/h2)
 | 
			
		||||
	if listener != nil {
 | 
			
		||||
		if config := v2tls.ConfigFromStreamSettings(streamSettings); config != nil {
 | 
			
		||||
			if tlsConfig := config.GetTLSConfig(); tlsConfig != nil {
 | 
			
		||||
				listener = tls.NewListener(listener, tlsConfig)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		l.listener = listener
 | 
			
		||||
 | 
			
		||||
		go func() {
 | 
			
		||||
			if err := l.server.Serve(l.listener); err != nil {
 | 
			
		||||
				errors.LogWarningInner(ctx, err, "failed to serve http for splithttp")
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
	}
 | 
			
		||||
	l.listener = listener
 | 
			
		||||
	if config := v2tls.ConfigFromStreamSettings(streamSettings); config != nil {
 | 
			
		||||
		if tlsConfig := config.GetTLSConfig(); tlsConfig != nil {
 | 
			
		||||
			listener = tls.NewListener(listener, tlsConfig)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return l, err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ package splithttp_test
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	gotls "crypto/tls"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	gonet "net"
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +11,9 @@ import (
 | 
			
		|||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/google/go-cmp/cmp"
 | 
			
		||||
	"github.com/xtls/xray-core/common"
 | 
			
		||||
	"github.com/xtls/xray-core/common/buf"
 | 
			
		||||
	"github.com/xtls/xray-core/common/net"
 | 
			
		||||
	"github.com/xtls/xray-core/common/protocol/tls/cert"
 | 
			
		||||
	"github.com/xtls/xray-core/testing/servers/tcp"
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +146,16 @@ func Test_listenSHAndDial_TLS(t *testing.T) {
 | 
			
		|||
	}
 | 
			
		||||
	listen, err := ListenSH(context.Background(), net.LocalHostIP, listenPort, streamSettings, func(conn stat.Connection) {
 | 
			
		||||
		go func() {
 | 
			
		||||
			_ = conn.Close()
 | 
			
		||||
			defer conn.Close()
 | 
			
		||||
 | 
			
		||||
			var b [1024]byte
 | 
			
		||||
			conn.SetReadDeadline(time.Now().Add(2 * time.Second))
 | 
			
		||||
			_, err := conn.Read(b[:])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			common.Must2(conn.Write([]byte("Response")))
 | 
			
		||||
		}()
 | 
			
		||||
	})
 | 
			
		||||
	common.Must(err)
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +163,15 @@ func Test_listenSHAndDial_TLS(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	conn, err := Dial(context.Background(), net.TCPDestination(net.DomainAddress("localhost"), listenPort), streamSettings)
 | 
			
		||||
	common.Must(err)
 | 
			
		||||
	_ = conn.Close()
 | 
			
		||||
 | 
			
		||||
	_, err = conn.Write([]byte("Test connection 1"))
 | 
			
		||||
	common.Must(err)
 | 
			
		||||
 | 
			
		||||
	var b [1024]byte
 | 
			
		||||
	n, _ := conn.Read(b[:])
 | 
			
		||||
	if string(b[:n]) != "Response" {
 | 
			
		||||
		t.Error("response: ", string(b[:n]))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	end := time.Now()
 | 
			
		||||
	if !end.Before(start.Add(time.Second * 5)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -229,15 +249,49 @@ func Test_listenSHAndDial_QUIC(t *testing.T) {
 | 
			
		|||
	}
 | 
			
		||||
	listen, err := ListenSH(context.Background(), net.LocalHostIP, listenPort, streamSettings, func(conn stat.Connection) {
 | 
			
		||||
		go func() {
 | 
			
		||||
			_ = conn.Close()
 | 
			
		||||
			defer conn.Close()
 | 
			
		||||
 | 
			
		||||
			b := buf.New()
 | 
			
		||||
			defer b.Release()
 | 
			
		||||
 | 
			
		||||
			for {
 | 
			
		||||
				b.Clear()
 | 
			
		||||
				if _, err := b.ReadFrom(conn); err != nil {
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				common.Must2(conn.Write(b.Bytes()))
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
	})
 | 
			
		||||
	common.Must(err)
 | 
			
		||||
	defer listen.Close()
 | 
			
		||||
 | 
			
		||||
	time.Sleep(time.Second)
 | 
			
		||||
 | 
			
		||||
	conn, err := Dial(context.Background(), net.UDPDestination(net.DomainAddress("localhost"), listenPort), streamSettings)
 | 
			
		||||
	common.Must(err)
 | 
			
		||||
	_ = conn.Close()
 | 
			
		||||
	defer conn.Close()
 | 
			
		||||
 | 
			
		||||
	const N = 1024
 | 
			
		||||
	b1 := make([]byte, N)
 | 
			
		||||
	common.Must2(rand.Read(b1))
 | 
			
		||||
	b2 := buf.New()
 | 
			
		||||
 | 
			
		||||
	common.Must2(conn.Write(b1))
 | 
			
		||||
 | 
			
		||||
	b2.Clear()
 | 
			
		||||
	common.Must2(b2.ReadFullFrom(conn, N))
 | 
			
		||||
	if r := cmp.Diff(b2.Bytes(), b1); r != "" {
 | 
			
		||||
		t.Error(r)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	common.Must2(conn.Write(b1))
 | 
			
		||||
 | 
			
		||||
	b2.Clear()
 | 
			
		||||
	common.Must2(b2.ReadFullFrom(conn, N))
 | 
			
		||||
	if r := cmp.Diff(b2.Bytes(), b1); r != "" {
 | 
			
		||||
		t.Error(r)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	end := time.Now()
 | 
			
		||||
	if !end.Before(start.Add(time.Second * 5)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue