mirror of https://github.com/ehang-io/nps
parent
86deb2025f
commit
4994476af1
|
@ -103,6 +103,7 @@ func (s *TRPClient) dealChan() error {
|
||||||
//与目标建立连接
|
//与目标建立连接
|
||||||
server, err := net.Dial("tcp", host)
|
server, err := net.Dial("tcp", host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//创建成功后io.copy
|
//创建成功后io.copy
|
||||||
|
|
35
conn.go
35
conn.go
|
@ -7,6 +7,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/url"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -95,6 +98,38 @@ func (s *Conn) SetAlive() {
|
||||||
conn.SetKeepAlivePeriod(time.Duration(2 * time.Second))
|
conn.SetKeepAlivePeriod(time.Duration(2 * time.Second))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//从tcp报文中解析出host
|
||||||
|
func (s *Conn) GetHost() (method, address string, rb []byte, err error) {
|
||||||
|
var b [2048]byte
|
||||||
|
var n int
|
||||||
|
var host string
|
||||||
|
if n, err = s.Read(b[:]); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rb = b[:n]
|
||||||
|
//TODO:某些不规范报文可能会有问题
|
||||||
|
fmt.Sscanf(string(b[:n]), "%s", &method)
|
||||||
|
reg, err := regexp.Compile(`(\w+:\/\/)([^/:]+)(:\d*)?`)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
host = string(reg.Find(b[:]))
|
||||||
|
hostPortURL, err := url.Parse(host)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if hostPortURL.Opaque == "443" { //https访问
|
||||||
|
address = hostPortURL.Scheme + ":443"
|
||||||
|
} else { //http访问
|
||||||
|
if strings.Index(hostPortURL.Host, ":") == -1 { //host不带端口, 默认80
|
||||||
|
address = hostPortURL.Host + ":80"
|
||||||
|
} else {
|
||||||
|
address = hostPortURL.Host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Conn) Close() error {
|
func (s *Conn) Close() error {
|
||||||
return s.conn.Close()
|
return s.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
9
main.go
9
main.go
|
@ -47,13 +47,14 @@ func main() {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
} else if *rpMode == "tunnelServer" {
|
} else if *rpMode == "tunnelServer" {
|
||||||
svr := NewTunnelModeServer(*tcpPort, *httpPort, *tunnelTarget)
|
svr := NewTunnelModeServer(*tcpPort, *httpPort, *tunnelTarget, ProcessTunnel)
|
||||||
if err := svr.Start(); err != nil {
|
svr.Start()
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
} else if *rpMode == "sock5Server" {
|
} else if *rpMode == "sock5Server" {
|
||||||
svr := NewSock5ModeServer(*tcpPort, *httpPort)
|
svr := NewSock5ModeServer(*tcpPort, *httpPort)
|
||||||
svr.Start()
|
svr.Start()
|
||||||
|
} else if *rpMode == "httpProxyServer" {
|
||||||
|
svr := NewTunnelModeServer(*tcpPort, *httpPort, *tunnelTarget, ProcessHttp)
|
||||||
|
svr.Start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
41
server.go
41
server.go
|
@ -125,19 +125,22 @@ func (s *HttpModeServer) writeResponse(w http.ResponseWriter, c *Conn) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type process func(c *Conn, s *TunnelModeServer) error
|
||||||
type TunnelModeServer struct {
|
type TunnelModeServer struct {
|
||||||
Tunnel
|
Tunnel
|
||||||
httpPort int
|
httpPort int
|
||||||
tunnelTarget string
|
tunnelTarget string
|
||||||
|
process process
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTunnelModeServer(tcpPort, httpPort int, tunnelTarget string) *TunnelModeServer {
|
func NewTunnelModeServer(tcpPort, httpPort int, tunnelTarget string, process process) *TunnelModeServer {
|
||||||
s := new(TunnelModeServer)
|
s := new(TunnelModeServer)
|
||||||
s.tunnelPort = tcpPort
|
s.tunnelPort = tcpPort
|
||||||
s.httpPort = httpPort
|
s.httpPort = httpPort
|
||||||
s.tunnelTarget = tunnelTarget
|
s.tunnelTarget = tunnelTarget
|
||||||
s.tunnelList = make(chan *Conn, 1000)
|
s.tunnelList = make(chan *Conn, 1000)
|
||||||
s.signalList = make(chan *Conn, 10)
|
s.signalList = make(chan *Conn, 10)
|
||||||
|
s.process = process
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,21 +167,43 @@ func (s *TunnelModeServer) startTunnelServer() {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go s.process(NewConn(conn))
|
go s.process(NewConn(conn), s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//监听连接处理
|
//TODO:这种实现方式……
|
||||||
func (s *TunnelModeServer) process(c *Conn) error {
|
//tcp隧道模式
|
||||||
|
func ProcessTunnel(c *Conn, s *TunnelModeServer) error {
|
||||||
retry:
|
retry:
|
||||||
if len(s.tunnelList) < 10 { //新建通道
|
link := s.GetTunnel()
|
||||||
go s.newChan()
|
|
||||||
}
|
|
||||||
link := <-s.tunnelList
|
|
||||||
if _, err := link.WriteHost(s.tunnelTarget); err != nil {
|
if _, err := link.WriteHost(s.tunnelTarget); err != nil {
|
||||||
|
link.Close()
|
||||||
goto retry
|
goto retry
|
||||||
}
|
}
|
||||||
go relay(link.conn, c.conn)
|
go relay(link.conn, c.conn)
|
||||||
relay(c.conn, link.conn)
|
relay(c.conn, link.conn)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//http代理模式
|
||||||
|
func ProcessHttp(c *Conn, s *TunnelModeServer) error {
|
||||||
|
method, addr, rb, err := c.GetHost()
|
||||||
|
if err != nil {
|
||||||
|
c.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
retry:
|
||||||
|
link := s.GetTunnel()
|
||||||
|
if _, err := link.WriteHost(addr); err != nil {
|
||||||
|
link.Close()
|
||||||
|
goto retry
|
||||||
|
}
|
||||||
|
if method == "CONNECT" {
|
||||||
|
fmt.Fprint(c, "HTTP/1.1 200 Connection established\r\n")
|
||||||
|
} else {
|
||||||
|
link.Write(rb)
|
||||||
|
}
|
||||||
|
go relay(link.conn, c.conn)
|
||||||
|
relay(c.conn, link.conn)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
10
tunnel.go
10
tunnel.go
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -91,8 +90,15 @@ retry:
|
||||||
connPass := <-s.signalList
|
connPass := <-s.signalList
|
||||||
_, err := connPass.conn.Write([]byte("chan"))
|
_, err := connPass.conn.Write([]byte("chan"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
log.Println(err)
|
||||||
goto retry
|
goto retry
|
||||||
}
|
}
|
||||||
s.signalList <- connPass
|
s.signalList <- connPass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Tunnel) GetTunnel() *Conn {
|
||||||
|
if len(s.tunnelList) < 10 { //新建通道
|
||||||
|
go s.newChan()
|
||||||
|
}
|
||||||
|
return <-s.tunnelList
|
||||||
|
}
|
||||||
|
|
14
util.go
14
util.go
|
@ -8,7 +8,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
|
@ -21,15 +20,10 @@ var (
|
||||||
disabledRedirect = errors.New("disabled redirect.")
|
disabledRedirect = errors.New("disabled redirect.")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func BadRequest(w http.ResponseWriter) {
|
func BadRequest(w http.ResponseWriter) {
|
||||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//发送请求并转为bytes
|
//发送请求并转为bytes
|
||||||
func GetEncodeResponse(req *http.Request) ([]byte, error) {
|
func GetEncodeResponse(req *http.Request) ([]byte, error) {
|
||||||
var respBytes []byte
|
var respBytes []byte
|
||||||
|
@ -52,7 +46,6 @@ func GetEncodeResponse(req *http.Request) ([]byte, error) {
|
||||||
return respBytes, nil
|
return respBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 将request 的处理
|
// 将request 的处理
|
||||||
func EncodeRequest(r *http.Request) ([]byte, error) {
|
func EncodeRequest(r *http.Request) ([]byte, error) {
|
||||||
raw := bytes.NewBuffer([]byte{})
|
raw := bytes.NewBuffer([]byte{})
|
||||||
|
@ -91,6 +84,7 @@ func DecodeRequest(data []byte) (*http.Request, error) {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
}
|
}
|
||||||
req.URL, _ = url.Parse(fmt.Sprintf("%s://%s%s", scheme, req.Host, req.RequestURI))
|
req.URL, _ = url.Parse(fmt.Sprintf("%s://%s%s", scheme, req.Host, req.RequestURI))
|
||||||
|
fmt.Println(req.URL)
|
||||||
req.RequestURI = ""
|
req.RequestURI = ""
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
@ -151,8 +145,6 @@ func replaceHost(resp []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func relay(in, out net.Conn) {
|
func relay(in, out net.Conn) {
|
||||||
if _, err := io.Copy(in, out); err != nil {
|
io.Copy(in, out);
|
||||||
log.Println("copy error:", err)
|
in.Close()
|
||||||
}
|
|
||||||
in.Close() //
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue