fix port forwarding
This commit is contained in:
parent
6baa9960f4
commit
0991952f0c
15
chain.go
15
chain.go
@ -48,6 +48,19 @@ func (c *ProxyChain) Nodes() []ProxyNode {
|
|||||||
return c.nodes
|
return c.nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ProxyChain) GetNode(index int) *ProxyNode {
|
||||||
|
if index < len(c.nodes) {
|
||||||
|
return &c.nodes[index]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProxyChain) SetNode(index int, node ProxyNode) {
|
||||||
|
if index < len(c.nodes) {
|
||||||
|
c.nodes[index] = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TryEnableHttp2 initialize HTTP2 if available.
|
// TryEnableHttp2 initialize HTTP2 if available.
|
||||||
// HTTP2 will be enabled when at least one HTTP2 proxy node (scheme == http2) is present.
|
// HTTP2 will be enabled when at least one HTTP2 proxy node (scheme == http2) is present.
|
||||||
//
|
//
|
||||||
@ -63,7 +76,7 @@ func (c *ProxyChain) TryEnableHttp2() {
|
|||||||
// HTTP2 restrict: HTTP2 will be enabled when at least one HTTP2 proxy node is present.
|
// HTTP2 restrict: HTTP2 will be enabled when at least one HTTP2 proxy node is present.
|
||||||
for i, node := range c.nodes {
|
for i, node := range c.nodes {
|
||||||
if node.Transport == "http2" {
|
if node.Transport == "http2" {
|
||||||
glog.V(LINFO).Infoln("http2 enabled")
|
glog.V(LINFO).Infoln("HTTP2 enabled")
|
||||||
cfg := &tls.Config{
|
cfg := &tls.Config{
|
||||||
InsecureSkipVerify: node.insecureSkipVerify(),
|
InsecureSkipVerify: node.insecureSkipVerify(),
|
||||||
ServerName: node.serverName,
|
ServerName: node.serverName,
|
||||||
|
47
http.go
47
http.go
@ -3,13 +3,13 @@ package gost
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"encoding/base64"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
//"encoding/base64"
|
|
||||||
//"strings"
|
//"strings"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
@ -62,15 +62,11 @@ func (s *HttpServer) HandleRequest(req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: forward http request
|
// TODO: forward http request
|
||||||
/*
|
lastNode := s.Base.Chain.lastNode
|
||||||
if len(forwardArgs) > 0 {
|
if lastNode != nil && (lastNode.Protocol == "http" || lastNode.Protocol == "") {
|
||||||
last := forwardArgs[len(forwardArgs)-1]
|
s.forwardRequest(req)
|
||||||
if last.Protocol == "http" || last.Protocol == "" {
|
|
||||||
forwardHttpRequest(req, conn, arg)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
c, err := s.Base.Chain.Dial(req.Host)
|
c, err := s.Base.Chain.Dial(req.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,6 +100,41 @@ func (s *HttpServer) HandleRequest(req *http.Request) {
|
|||||||
glog.V(LINFO).Infof("[http] %s >-< %s", s.conn.RemoteAddr(), req.Host)
|
glog.V(LINFO).Infof("[http] %s >-< %s", s.conn.RemoteAddr(), req.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *HttpServer) forwardRequest(req *http.Request) {
|
||||||
|
last := s.Base.Chain.lastNode
|
||||||
|
if last == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cc, err := s.Base.Chain.GetConn()
|
||||||
|
if err != nil {
|
||||||
|
glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), last.Addr, err)
|
||||||
|
|
||||||
|
b := []byte("HTTP/1.1 503 Service unavailable\r\n" +
|
||||||
|
"Proxy-Agent: gost/" + Version + "\r\n\r\n")
|
||||||
|
glog.V(LDEBUG).Infof("[http] %s <- %s\n%s", s.conn.RemoteAddr(), last.Addr, string(b))
|
||||||
|
s.conn.Write(b)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cc.Close()
|
||||||
|
|
||||||
|
if last.User != nil {
|
||||||
|
req.Header.Set("Proxy-Authorization",
|
||||||
|
"Basic "+base64.StdEncoding.EncodeToString([]byte(last.User.String())))
|
||||||
|
}
|
||||||
|
|
||||||
|
cc.SetWriteDeadline(time.Now().Add(WriteTimeout))
|
||||||
|
if err = req.WriteProxy(cc); err != nil {
|
||||||
|
glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), req.Host, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cc.SetWriteDeadline(time.Time{})
|
||||||
|
|
||||||
|
glog.V(LINFO).Infof("[http] %s <-> %s", s.conn.RemoteAddr(), req.Host)
|
||||||
|
s.Base.transport(s.conn, cc)
|
||||||
|
glog.V(LINFO).Infof("[http] %s >-< %s", s.conn.RemoteAddr(), req.Host)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type Http2Server struct {
|
type Http2Server struct {
|
||||||
Base *ProxyServer
|
Base *ProxyServer
|
||||||
Handler http.Handler
|
Handler http.Handler
|
||||||
|
49
socks.go
49
socks.go
@ -316,54 +316,63 @@ func (s *Socks5Server) handleUDPRelay(req *gosocks5.Request) {
|
|||||||
cc, err := s.Base.Chain.GetConn()
|
cc, err := s.Base.Chain.GetConn()
|
||||||
// connection error
|
// connection error
|
||||||
if err != nil && err != ErrEmptyChain {
|
if err != nil && err != ErrEmptyChain {
|
||||||
glog.V(LWARNING).Infof("[udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), socksAddr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// serve as standard socks5 udp relay
|
// serve as standard socks5 udp relay local <-> remote
|
||||||
if err == ErrEmptyChain {
|
if err == ErrEmptyChain {
|
||||||
peer, err := net.ListenUDP("udp", nil)
|
peer, er := net.ListenUDP("udp", nil)
|
||||||
if err != nil {
|
if er != nil {
|
||||||
glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), socksAddr, er)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer peer.Close()
|
defer peer.Close()
|
||||||
|
|
||||||
go s.transportUDP(relay, peer)
|
go s.transportUDP(relay, peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// forward udp local <-> tunnel
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer cc.Close()
|
defer cc.Close()
|
||||||
|
|
||||||
cc.SetWriteDeadline(time.Now().Add(WriteTimeout))
|
cc.SetWriteDeadline(time.Now().Add(WriteTimeout))
|
||||||
if err := gosocks5.NewRequest(CmdUdpTun, nil).Write(cc); err != nil {
|
req := gosocks5.NewRequest(CmdUdpTun, nil)
|
||||||
glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
if err := req.Write(cc); err != nil {
|
||||||
|
glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), cc.RemoteAddr(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cc.SetWriteDeadline(time.Time{})
|
cc.SetWriteDeadline(time.Time{})
|
||||||
|
glog.V(LDEBUG).Infof("[socks5-udp] %s -> %s\n%s", s.conn.RemoteAddr(), cc.RemoteAddr(), req)
|
||||||
|
|
||||||
cc.SetReadDeadline(time.Now().Add(ReadTimeout))
|
cc.SetReadDeadline(time.Now().Add(ReadTimeout))
|
||||||
reply, err = gosocks5.ReadReply(cc)
|
reply, err = gosocks5.ReadReply(cc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), cc.RemoteAddr(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), cc.RemoteAddr(), reply)
|
||||||
|
|
||||||
if reply.Rep != gosocks5.Succeeded {
|
if reply.Rep != gosocks5.Succeeded {
|
||||||
glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : udp associate error", s.conn.RemoteAddr(), req.Addr)
|
glog.V(LWARNING).Infoln("[socks5-udp] %s <- %s : udp associate failed", s.conn.RemoteAddr(), cc.RemoteAddr())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cc.SetReadDeadline(time.Time{})
|
cc.SetReadDeadline(time.Time{})
|
||||||
|
glog.V(LINFO).Infof("[socks5-udp] %s <-> %s [tun: %s]", s.conn.RemoteAddr(), socksAddr, reply.Addr)
|
||||||
|
|
||||||
go s.tunnelUDP(relay, cc, true)
|
go s.tunnelUDP(relay, cc, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.V(LINFO).Infof("[socks5-udp] %s <-> %s", s.conn.RemoteAddr(), req.Addr)
|
glog.V(LINFO).Infof("[socks5-udp] %s <-> %s", s.conn.RemoteAddr(), socksAddr)
|
||||||
b := make([]byte, SmallBufferSize)
|
b := make([]byte, SmallBufferSize)
|
||||||
for {
|
for {
|
||||||
_, err := s.conn.Read(b) // discard any data from tcp connection
|
_, err := s.conn.Read(b) // discard any data from tcp connection
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
glog.V(LWARNING).Infof("[socks5-udp] %s - %s : %s", s.conn.RemoteAddr(), socksAddr, err)
|
||||||
break // client disconnected
|
break // client disconnected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glog.V(LINFO).Infof("[socks5-udp] %s >-< %s", s.conn.RemoteAddr(), req.Addr)
|
glog.V(LINFO).Infof("[socks5-udp] %s >-< %s", s.conn.RemoteAddr(), socksAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
||||||
@ -371,10 +380,10 @@ func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
|||||||
|
|
||||||
// connection error
|
// connection error
|
||||||
if err != nil && err != ErrEmptyChain {
|
if err != nil && err != ErrEmptyChain {
|
||||||
glog.V(LWARNING).Infof("[socks5-udp] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
||||||
reply := gosocks5.NewReply(gosocks5.Failure, nil)
|
reply := gosocks5.NewReply(gosocks5.Failure, nil)
|
||||||
reply.Write(s.conn)
|
reply.Write(s.conn)
|
||||||
glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, reply)
|
glog.V(LDEBUG).Infof("[socks5-udp] %s -> %s\n%s", s.conn.RemoteAddr(), req.Addr, reply)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +392,7 @@ func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
|||||||
bindAddr, _ := net.ResolveUDPAddr("udp", req.Addr.String())
|
bindAddr, _ := net.ResolveUDPAddr("udp", req.Addr.String())
|
||||||
uc, err := net.ListenUDP("udp", bindAddr)
|
uc, err := net.ListenUDP("udp", bindAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(LWARNING).Infof("[socks5-udp] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer uc.Close()
|
defer uc.Close()
|
||||||
@ -392,14 +401,14 @@ func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
|||||||
socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String())
|
socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String())
|
||||||
reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr)
|
reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr)
|
||||||
if err := reply.Write(s.conn); err != nil {
|
if err := reply.Write(s.conn); err != nil {
|
||||||
glog.V(LWARNING).Infof("[socks5-udp] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
glog.V(LWARNING).Infof("[socks5-udp] %s <- %s : %s", s.conn.RemoteAddr(), socksAddr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), uc.LocalAddr(), reply)
|
glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), socksAddr, reply)
|
||||||
|
|
||||||
glog.V(LINFO).Infof("[socks5-udp] %s <-> %s", s.conn.RemoteAddr(), uc.LocalAddr())
|
glog.V(LINFO).Infof("[socks5-udp] %s <-> %s", s.conn.RemoteAddr(), socksAddr)
|
||||||
s.tunnelUDP(uc, s.conn, false)
|
s.tunnelUDP(uc, s.conn, false)
|
||||||
glog.V(LINFO).Infof("[socks5-udp] %s >-< %s", s.conn.RemoteAddr(), uc.LocalAddr())
|
glog.V(LINFO).Infof("[socks5-udp] %s >-< %s", s.conn.RemoteAddr(), socksAddr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,9 +417,9 @@ func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
|||||||
// tunnel <-> tunnel, direct forwarding
|
// tunnel <-> tunnel, direct forwarding
|
||||||
req.Write(cc)
|
req.Write(cc)
|
||||||
|
|
||||||
glog.V(LINFO).Infof("[socks5-udp] %s <-> %s[tun]", s.conn.RemoteAddr(), cc.RemoteAddr())
|
glog.V(LINFO).Infof("[socks5-udp] %s <-> %s [tun]", s.conn.RemoteAddr(), cc.RemoteAddr())
|
||||||
s.Base.transport(s.conn, cc)
|
s.Base.transport(s.conn, cc)
|
||||||
glog.V(LINFO).Infof("[socks5-udp] %s >-< %s[tun]", s.conn.RemoteAddr(), cc.RemoteAddr())
|
glog.V(LINFO).Infof("[socks5-udp] %s >-< %s [tun]", s.conn.RemoteAddr(), cc.RemoteAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Socks5Server) bind(addr string) (net.Conn, error) {
|
func (s *Socks5Server) bind(addr string) (net.Conn, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user