Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
46b1719
Add TLS1.2 AEAD explicit nonce detection
xiaokangwang Jul 3, 2025
508ed96
Add TLS1.2 AEAD explicit nonce processing
xiaokangwang Jul 3, 2025
7b74406
fix not using tag in tlsmirror encryption key derivation
xiaokangwang Jul 3, 2025
ebe1fc7
fix corrupted tls12 aead stream in tls mirror
xiaokangwang Jul 3, 2025
f0c0614
update nonce counter for tls12 encrypted alert as well.
xiaokangwang Jul 3, 2025
1825040
support connection invalidation in tlsmirror
xiaokangwang Jul 3, 2025
ed59fb1
avoid message copy deadlock in message writers and stop copy when ale…
xiaokangwang Jul 3, 2025
0785a8e
when there is an error, disable message inserting and drain copy sockets
xiaokangwang Jul 3, 2025
879a7a0
rework wait time in traffic generator
xiaokangwang Jul 4, 2025
f64761c
add default no wait for wait time spec
xiaokangwang Jul 4, 2025
6fc44f5
add first write delay to compensate for timing issue created by forwa…
xiaokangwang Jul 4, 2025
e6f5e02
add transport layer padding support to tlsmirror
xiaokangwang Jul 4, 2025
7dbba16
add todo for clientside close
xiaokangwang Jul 4, 2025
493c1d5
add server side first write delay
xiaokangwang Jul 4, 2025
f94f99f
rewrite first write delay calculation to handle edge case
xiaokangwang Jul 4, 2025
336bdb6
fix transport layer padding issue with tlsmirror
xiaokangwang Jul 4, 2025
6fb5471
move single connection HTTP transport implementation
xiaokangwang Jul 4, 2025
734c3b4
move single connection HTTP transport implementation
xiaokangwang Jul 4, 2025
5cce254
rename option to DeferInstanceDerivedWriteTime in tlsmirror
xiaokangwang Jul 4, 2025
817696f
fix lint issues in tls mirror
xiaokangwang Jul 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/linters/.golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ linters:
- builtin$
- examples$
issues:
new: true
new: false
formatters:
enable:
- gofmt
Expand Down
7 changes: 7 additions & 0 deletions transport/internet/tls/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,13 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
}
}

if len(c.Ciphersuites) > 0 {
config.CipherSuites = make([]uint16, 0, len(c.Ciphersuites))
for _, cs := range c.Ciphersuites {
config.CipherSuites = append(config.CipherSuites, uint16(cs))
}
}

return config
}

Expand Down
19 changes: 15 additions & 4 deletions transport/internet/tls/config.pb.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,11 @@ type Config struct {
Ech_DOHserver string `protobuf:"bytes,17,opt,name=ech_DOHserver,json=echDOHserver,proto3" json:"ech_DOHserver,omitempty"`
// domain to query for https record
EchQueryDomain string `protobuf:"bytes,18,opt,name=ech_query_domain,json=echQueryDomain,proto3" json:"ech_query_domain,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
// cipher suites to to be offered or accepted.
// This is an developer option.
Ciphersuites []uint32 `protobuf:"varint,19,rep,packed,name=ciphersuites,proto3" json:"ciphersuites,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}

func (x *Config) Reset() {
Expand Down Expand Up @@ -367,6 +370,13 @@ func (x *Config) GetEchQueryDomain() string {
return ""
}

func (x *Config) GetCiphersuites() []uint32 {
if x != nil {
return x.Ciphersuites
}
return nil
}

var File_transport_internet_tls_config_proto protoreflect.FileDescriptor

const file_transport_internet_tls_config_proto_rawDesc = "" +
Expand All @@ -382,7 +392,7 @@ const file_transport_internet_tls_config_proto_rawDesc = "" +
"\fENCIPHERMENT\x10\x00\x12\x14\n" +
"\x10AUTHORITY_VERIFY\x10\x01\x12\x13\n" +
"\x0fAUTHORITY_ISSUE\x10\x02\x12\x1b\n" +
"\x17AUTHORITY_VERIFY_CLIENT\x10\x03\"\xa0\a\n" +
"\x17AUTHORITY_VERIFY_CLIENT\x10\x03\"\xc4\a\n" +
"\x06Config\x12-\n" +
"\x0eallow_insecure\x18\x01 \x01(\bB\x06\x82\xb5\x18\x02(\x01R\rallowInsecure\x12P\n" +
"\vcertificate\x18\x02 \x03(\v2..v2ray.core.transport.internet.tls.CertificateR\vcertificate\x12\x1f\n" +
Expand All @@ -402,7 +412,8 @@ const file_transport_internet_tls_config_proto_rawDesc = "" +
"\n" +
"ech_config\x18\x10 \x01(\fR\techConfig\x12#\n" +
"\rech_DOHserver\x18\x11 \x01(\tR\fechDOHserver\x12(\n" +
"\x10ech_query_domain\x18\x12 \x01(\tR\x0eechQueryDomain\"I\n" +
"\x10ech_query_domain\x18\x12 \x01(\tR\x0eechQueryDomain\x12\"\n" +
"\fciphersuites\x18\x13 \x03(\rR\fciphersuites\"I\n" +
"\n" +
"TLSVersion\x12\v\n" +
"\aDefault\x10\x00\x12\n" +
Expand Down
4 changes: 4 additions & 0 deletions transport/internet/tls/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,8 @@ message Config {

// domain to query for https record
string ech_query_domain = 18;

// cipher suites to to be offered or accepted.
// This is an developer option.
repeated uint32 ciphersuites = 19;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package httponconnection

import "github.com/v2fly/v2ray-core/v5/common/errors"

type errPathObjHolder struct{}

func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}
82 changes: 82 additions & 0 deletions transport/internet/tlsmirror/httponconnection/singleconnhttp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package httponconnection

import (
"bufio"
"net"
"net/http"

"golang.org/x/net/http2"
)

//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen

type HttpRequestTransport interface {
http.RoundTripper
}

func newHTTPRequestTransportH1(conn net.Conn) HttpRequestTransport {
return &httpRequestTransportH1{
conn: conn,
bufReader: bufio.NewReader(conn),
}
}

type httpRequestTransportH1 struct {
conn net.Conn
bufReader *bufio.Reader
}

func (h *httpRequestTransportH1) RoundTrip(req *http.Request) (*http.Response, error) {
req.Proto = "HTTP/1.1"
req.ProtoMajor = 1
req.ProtoMinor = 1

err := req.Write(h.conn)
if err != nil {
return nil, err
}
return http.ReadResponse(h.bufReader, req)
}

func newHTTPRequestTransportH2(conn net.Conn) HttpRequestTransport {
transport := &http2.Transport{}
clientConn, err := transport.NewClientConn(conn)
if err != nil {
return nil
}
return &httpRequestTransportH2{
transport: transport,
clientConnection: clientConn,
}
}

type httpRequestTransportH2 struct {
transport *http2.Transport
clientConnection *http2.ClientConn
}

func (h *httpRequestTransportH2) RoundTrip(request *http.Request) (*http.Response, error) {
request.ProtoMajor = 2
request.ProtoMinor = 0

response, err := h.clientConnection.RoundTrip(request)
if err != nil {
return nil, err
}
return response, nil
}

func newSingleConnectionHTTPTransport(conn net.Conn, alpn string) (HttpRequestTransport, error) {
switch alpn {
case "h2":
return newHTTPRequestTransportH2(conn), nil
case "http/1.1", "":
return newHTTPRequestTransportH1(conn), nil
default:
return nil, newError("unknown alpn: " + alpn).AtWarning()
}
}

func NewSingleConnectionHTTPTransport(conn net.Conn, alpn string) (HttpRequestTransport, error) {
return newSingleConnectionHTTPTransport(conn, alpn)
}
4 changes: 4 additions & 0 deletions transport/internet/tlsmirror/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,20 @@ type PartialTLSRecordRejectProfile interface {

type MessageHook func(message *TLSRecord) (drop bool, ok error)

type ExplicitNonceDetection func(cipherSuite uint16) bool

type InsertableTLSConn interface {
common.Closable
GetHandshakeRandom() ([]byte, []byte, error)
InsertC2SMessage(message *TLSRecord) error
InsertS2CMessage(message *TLSRecord) error
GetApplicationDataExplicitNonceReservedOverheadHeaderLength() (int, error)
}

const TrafficGeneratorManagedConnectionContextKey = "TrafficGeneratorManagedConnection-ku63HMMD-kduCPhr8-DN4y6WEa"

type TrafficGeneratorManagedConnection interface {
RecallTrafficGenerator() error
WaitConnectionReady() context.Context
IsConnectionInvalidated() bool
}
Loading
Loading