experimental quic support
This commit is contained in:
parent
6ca1f4a984
commit
e0b8e54619
2
gost.go
2
gost.go
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
Version = "2.2-rc2"
|
||||
Version = "2.3-dev"
|
||||
)
|
||||
|
||||
// Log level for glog
|
||||
|
2
node.go
2
node.go
@ -57,7 +57,7 @@ func ParseProxyNode(s string) (node ProxyNode, err error) {
|
||||
}
|
||||
|
||||
switch node.Transport {
|
||||
case "ws", "wss", "tls", "http2":
|
||||
case "ws", "wss", "tls", "http2", "ssu", "quic":
|
||||
case "https":
|
||||
node.Protocol = "http"
|
||||
node.Transport = "tls"
|
||||
|
80
quic.go
Normal file
80
quic.go
Normal file
@ -0,0 +1,80 @@
|
||||
package gost
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"github.com/golang/glog"
|
||||
"github.com/lucas-clemente/quic-go/h2quic"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
)
|
||||
|
||||
type QuicServer struct {
|
||||
Base *ProxyServer
|
||||
Handler http.Handler
|
||||
TLSConfig *tls.Config
|
||||
}
|
||||
|
||||
func NewQuicServer(base *ProxyServer) *QuicServer {
|
||||
return &QuicServer{Base: base}
|
||||
}
|
||||
|
||||
func (s *QuicServer) ListenAndServeTLS(config *tls.Config) error {
|
||||
server := &h2quic.Server{
|
||||
Server: &http.Server{
|
||||
Addr: s.Base.Node.Addr,
|
||||
Handler: s.Handler,
|
||||
TLSConfig: config,
|
||||
},
|
||||
}
|
||||
if server.Handler == nil {
|
||||
server.Handler = http.HandlerFunc(s.HandleRequest)
|
||||
}
|
||||
return server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (s *QuicServer) HandleRequest(w http.ResponseWriter, req *http.Request) {
|
||||
target := req.Host
|
||||
glog.V(LINFO).Infof("[quic] %s %s - %s %s", req.Method, req.RemoteAddr, target, req.Proto)
|
||||
|
||||
if glog.V(LDEBUG) {
|
||||
dump, _ := httputil.DumpRequest(req, false)
|
||||
glog.Infoln(string(dump))
|
||||
}
|
||||
|
||||
c, err := s.Base.Chain.Dial(target)
|
||||
if err != nil {
|
||||
glog.V(LWARNING).Infof("[quic] %s -> %s : %s", req.RemoteAddr, target, err)
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
glog.V(LINFO).Infof("[quic] %s <-> %s", req.RemoteAddr, target)
|
||||
|
||||
req.Header.Set("Connection", "Keep-Alive")
|
||||
if err = req.Write(c); err != nil {
|
||||
glog.V(LWARNING).Infof("[quic] %s -> %s : %s", req.RemoteAddr, target, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := http.ReadResponse(bufio.NewReader(c), req)
|
||||
if err != nil {
|
||||
glog.V(LWARNING).Infoln(err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
for k, v := range resp.Header {
|
||||
for _, vv := range v {
|
||||
w.Header().Add(k, vv)
|
||||
}
|
||||
}
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
if _, err := io.Copy(flushWriter{w}, resp.Body); err != nil {
|
||||
glog.V(LWARNING).Infof("[quic] %s <- %s : %s", req.RemoteAddr, target, err)
|
||||
}
|
||||
|
||||
glog.V(LINFO).Infof("[quic] %s >-< %s", req.RemoteAddr, target)
|
||||
}
|
@ -80,6 +80,10 @@ func (s *ProxyServer) Serve() error {
|
||||
return NewRTcpForwardServer(s).Serve()
|
||||
case "rudp": // Remote UDP port forwarding
|
||||
return NewRUdpForwardServer(s).Serve()
|
||||
case "ssu": // shadowsocks udp relay
|
||||
return NewShadowUdpServer(s).ListenAndServe()
|
||||
case "quic":
|
||||
return NewQuicServer(s).ListenAndServeTLS(s.TLSConfig)
|
||||
default:
|
||||
ln, err = net.Listen("tcp", node.Addr)
|
||||
}
|
||||
|
40
ss.go
40
ss.go
@ -65,6 +65,46 @@ func (s *ShadowServer) Serve() {
|
||||
glog.V(LINFO).Infof("[ss] %s >-< %s", s.conn.RemoteAddr(), addr)
|
||||
}
|
||||
|
||||
type ShadowUdpServer struct {
|
||||
Base *ProxyServer
|
||||
Handler func(conn *net.UDPConn, addr *net.UDPAddr, data []byte)
|
||||
}
|
||||
|
||||
func NewShadowUdpServer(base *ProxyServer) *ShadowUdpServer {
|
||||
return &ShadowUdpServer{Base: base}
|
||||
}
|
||||
|
||||
func (s *ShadowUdpServer) ListenAndServe() error {
|
||||
laddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lconn, err := net.ListenUDP("udp", laddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer lconn.Close()
|
||||
|
||||
if s.Handler == nil {
|
||||
s.Handler = s.HandleConn
|
||||
}
|
||||
|
||||
for {
|
||||
b := make([]byte, LargeBufferSize)
|
||||
n, addr, err := lconn.ReadFromUDP(b)
|
||||
if err != nil {
|
||||
glog.V(LWARNING).Infoln(err)
|
||||
continue
|
||||
}
|
||||
|
||||
go s.Handler(lconn, addr, b[:n])
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ShadowUdpServer) HandleConn(conn *net.UDPConn, addr *net.UDPAddr, data []byte) {
|
||||
|
||||
}
|
||||
|
||||
// This function is copied from shadowsocks library with some modification.
|
||||
func (s *ShadowServer) getRequest() (host string, ota bool, err error) {
|
||||
// buf size should at least have the same size with the largest possible
|
||||
|
Loading…
Reference in New Issue
Block a user