Skip to content

Commit

Permalink
recover fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
p4gefau1t committed Mar 24, 2020
1 parent da536ee commit 787b5e3
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 78 deletions.
8 changes: 2 additions & 6 deletions conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,10 @@ type TLSConfig struct {
CipherTLS13 string `json:"cipher_tls13"`
PreferServerCipher bool `json:"prefer_server_cipher"`
SNI string `json:"sni"`

HTTPFile string `json:"plain_http_response"`
ALPN []string `json:"alpn"`
ALPHPortOverride uint16 `json:"alpn_port_override"`
HTTPFile string `json:"plain_http_response"`
FallbackPort uint16 `json:"fallback_port"`

FallbackAddr net.Addr
FallbackHTTP bool
FallbackHTTP2 bool
CertPool *x509.CertPool
KeyPair []tls.Certificate
HTTPResponse []byte
Expand Down
16 changes: 2 additions & 14 deletions conf/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,24 +123,12 @@ func ParseJSON(data []byte) (*GlobalConfig, error) {
config.RemoteAddr = remoteAddr
config.RemoteIP = remoteAddr.IP

if len(config.TLS.ALPN) != 0 || config.TLS.ALPHPortOverride != 0 {
if config.TLS.ALPHPortOverride == 0 {
logger.Warn("alpn port override is unspecified. using remote port")
config.TLS.ALPHPortOverride = config.RemotePort
}
fallbackAddr, err := convertToAddr(config.TCP.PreferIPV4, config.RemoteHost, config.TLS.ALPHPortOverride)
if config.TLS.FallbackPort != 0 {
fallbackAddr, err := convertToAddr(config.TCP.PreferIPV4, config.RemoteHost, config.TLS.FallbackPort)
if err != nil {
return nil, common.NewError("invalid tls fallback address").Base(err)
}
config.TLS.FallbackAddr = fallbackAddr
for _, s := range config.TLS.ALPN {
if strings.Contains(s, "http") || strings.Contains(s, "HTTP") {
config.TLS.FallbackHTTP = true
}
if s == "h2" {
config.TLS.FallbackHTTP2 = true
}
}
}

if config.TLS.Cipher != "" || config.TLS.CipherTLS13 != "" {
Expand Down
70 changes: 13 additions & 57 deletions proxy/server.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package proxy

import (
"bufio"
"bytes"
"context"
"crypto/tls"
"database/sql"
"net"
"net/http"
"reflect"

"github.com/p4gefau1t/trojan-go/common"
Expand All @@ -18,7 +15,6 @@ import (
"github.com/p4gefau1t/trojan-go/protocol/trojan"
"github.com/p4gefau1t/trojan-go/stat"
"github.com/xtaci/smux"
"golang.org/x/net/http2"
)

type Server struct {
Expand Down Expand Up @@ -113,67 +109,27 @@ func (s *Server) handleConn(conn net.Conn) {
}

func (s *Server) handleInvalidConn(conn net.Conn, tlsConn *tls.Conn) {
//HACK
//obtain the bytes buffered by the tls conn

if len(s.config.TLS.HTTPResponse) > 0 {
logger.Warn("trying to response with a plain http response")
logger.Warn("trying to response a plain http response")
conn.Write(s.config.TLS.HTTPResponse)
conn.Close()
return
}

if s.config.TLS.FallbackAddr != nil {
//HACK
//obtain the bytes buffered by the tls conn
v := reflect.ValueOf(*tlsConn)
rawReq := v.FieldByName("rawInput").FieldByName("buf").Bytes()
v := reflect.ValueOf(*tlsConn)
buf := v.FieldByName("rawInput").FieldByName("buf").Bytes()
logger.Debug("payload:" + string(buf))

logger.Debug("paylaod:\n" + string(rawReq))
supportedALPN := false
if s.config.TLS.FallbackHTTP {
buffer := bytes.NewBuffer([]byte{})
buffer.Write(rawReq)
r := bufio.NewReader(buffer)
if _, err := http.ReadRequest(r); err == nil {
logger.Warn("incoming HTTP request:\n" + string(rawReq))
supportedALPN = true
}
}

if s.config.TLS.FallbackHTTP2 {
buffer := bytes.NewBuffer([]byte{})
buffer.Write(rawReq)
framer := http2.NewFramer(buffer, buffer)
if frame, err := framer.ReadFrame(); err == nil {
logger.Warn("incoming HTTP2 request:\n" + frame.Header().String())
supportedALPN = true
}
}

if supportedALPN {
remote, err := net.Dial("tcp", s.config.TLS.FallbackAddr.String())
if err != nil {
logger.Warn(common.NewError("failed to dial to tls fallback server").Base(err))
return
}
logger.Warn("proxying this invalid tls conn to the tls fallback server")
remote.Write(rawReq)
go proxyConn(conn, remote)
} else {
/*
logger.Warn("unknown protocol, closing")
conn.Close()
*/
//fuck, just proxy it
logger.Warn("unknown protocol")
remote, err := net.Dial("tcp", s.config.TLS.FallbackAddr.String())
if err != nil {
logger.Warn(common.NewError("failed to dial to tls fallback server").Base(err))
return
}
logger.Warn("proxying this invalid tls conn to the tls fallback server")
remote.Write(rawReq)
go proxyConn(conn, remote)
}
remote, err := net.Dial("tcp", s.config.TLS.FallbackAddr.String())
if err != nil {
logger.Warn(common.NewError("failed to dial to tls fallback server").Base(err))
}
logger.Warn("proxying this invalid tls conn to the tls fallback server")
remote.Write(buf)
go proxyConn(conn, remote)
}

func (s *Server) Run() error {
Expand Down
1 change: 0 additions & 1 deletion proxy/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ func TestServerTCPRedirecting(t *testing.T) {
addr, err := net.ResolveTCPAddr("tcp", "localhost:443")
common.Must(err)
config.TLS.FallbackAddr = addr
config.TLS.FallbackHTTP = true

server := Server{
config: config,
Expand Down

0 comments on commit 787b5e3

Please sign in to comment.