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
|
||||
}
|
||||
|
||||
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.
|
||||
// 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.
|
||||
for i, node := range c.nodes {
|
||||
if node.Transport == "http2" {
|
||||
glog.V(LINFO).Infoln("http2 enabled")
|
||||
glog.V(LINFO).Infoln("HTTP2 enabled")
|
||||
cfg := &tls.Config{
|
||||
InsecureSkipVerify: node.insecureSkipVerify(),
|
||||
ServerName: node.serverName,
|
||||
|
51
http.go
51
http.go
@ -3,13 +3,13 @@ package gost
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"github.com/golang/glog"
|
||||
"golang.org/x/net/http2"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
//"encoding/base64"
|
||||
//"strings"
|
||||
"errors"
|
||||
"time"
|
||||
@ -62,15 +62,11 @@ func (s *HttpServer) HandleRequest(req *http.Request) {
|
||||
}
|
||||
|
||||
// TODO: forward http request
|
||||
/*
|
||||
if len(forwardArgs) > 0 {
|
||||
last := forwardArgs[len(forwardArgs)-1]
|
||||
if last.Protocol == "http" || last.Protocol == "" {
|
||||
forwardHttpRequest(req, conn, arg)
|
||||
return
|
||||
}
|
||||
}
|
||||
*/
|
||||
lastNode := s.Base.Chain.lastNode
|
||||
if lastNode != nil && (lastNode.Protocol == "http" || lastNode.Protocol == "") {
|
||||
s.forwardRequest(req)
|
||||
return
|
||||
}
|
||||
|
||||
c, err := s.Base.Chain.Dial(req.Host)
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
Base *ProxyServer
|
||||
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()
|
||||
// connection error
|
||||
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
|
||||
}
|
||||
|
||||
// serve as standard socks5 udp relay
|
||||
// serve as standard socks5 udp relay local <-> remote
|
||||
if err == ErrEmptyChain {
|
||||
peer, err := net.ListenUDP("udp", nil)
|
||||
if err != nil {
|
||||
glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
||||
peer, er := net.ListenUDP("udp", nil)
|
||||
if er != nil {
|
||||
glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), socksAddr, er)
|
||||
return
|
||||
}
|
||||
defer peer.Close()
|
||||
|
||||
go s.transportUDP(relay, peer)
|
||||
}
|
||||
|
||||
// forward udp local <-> tunnel
|
||||
if err == nil {
|
||||
defer cc.Close()
|
||||
|
||||
cc.SetWriteDeadline(time.Now().Add(WriteTimeout))
|
||||
if err := gosocks5.NewRequest(CmdUdpTun, nil).Write(cc); err != nil {
|
||||
glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err)
|
||||
req := gosocks5.NewRequest(CmdUdpTun, nil)
|
||||
if err := req.Write(cc); err != nil {
|
||||
glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), cc.RemoteAddr(), err)
|
||||
return
|
||||
}
|
||||
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))
|
||||
reply, err = gosocks5.ReadReply(cc)
|
||||
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
|
||||
}
|
||||
glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), cc.RemoteAddr(), reply)
|
||||
|
||||
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
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
for {
|
||||
_, err := s.conn.Read(b) // discard any data from tcp connection
|
||||
if err != nil {
|
||||
glog.V(LWARNING).Infof("[socks5-udp] %s - %s : %s", s.conn.RemoteAddr(), socksAddr, err)
|
||||
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) {
|
||||
@ -371,10 +380,10 @@ func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
||||
|
||||
// connection error
|
||||
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.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
|
||||
}
|
||||
|
||||
@ -383,7 +392,7 @@ func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
||||
bindAddr, _ := net.ResolveUDPAddr("udp", req.Addr.String())
|
||||
uc, err := net.ListenUDP("udp", bindAddr)
|
||||
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
|
||||
}
|
||||
defer uc.Close()
|
||||
@ -392,14 +401,14 @@ func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
||||
socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String())
|
||||
reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr)
|
||||
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
|
||||
}
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
||||
@ -408,9 +417,9 @@ func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) {
|
||||
// tunnel <-> tunnel, direct forwarding
|
||||
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)
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user