609 lines
15 KiB
Go
609 lines
15 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"os/signal"
|
||
"proxy/services"
|
||
"syscall"
|
||
)
|
||
|
||
const APP_VERSION = "2.2"
|
||
|
||
// var (
|
||
// checker Checker
|
||
// certBytes []byte
|
||
// keyBytes []byte
|
||
// outPool ConnPool
|
||
// basicAuth BasicAuth
|
||
// )
|
||
|
||
func init() {
|
||
|
||
// return
|
||
// //Init
|
||
// err = Init()
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// isLocalHTTP := cfg.GetBool("local-http")
|
||
// isTLS := cfg.GetBool("local-tls") || cfg.GetBool("parent-tls")
|
||
// isTCP := isLocalHTTP || isTLS || cfg.GetBool("local-tcp") || cfg.GetBool("parent-tcp")
|
||
|
||
// //InitTCP
|
||
// if isTCP {
|
||
// err = InitTCP()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitTLS
|
||
// if isTLS {
|
||
// err = InitTLS()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitUDP
|
||
// if cfg.GetBool("local-udp") || cfg.GetBool("parent-udp") {
|
||
// err = InitUDP()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitLocal
|
||
// err = InitLocal()
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitLocalTCP
|
||
// if cfg.GetBool("local-tcp") || cfg.GetBool("local-tls") || isLocalHTTP {
|
||
// err = InitLocalTCP()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitLocalTLS
|
||
// if cfg.GetBool("local-tls") {
|
||
// err = InitLocalTLS()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitLocalHTTP
|
||
// if isLocalHTTP {
|
||
// err = InitLocalHTTP()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitLocalUDP
|
||
// if cfg.GetBool("local-udp") {
|
||
// err = InitLocalUDP()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitParent
|
||
// if cfg.GetString("parent") != "" {
|
||
// err = InitParent()
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitParentTCP
|
||
// if cfg.GetBool("parent-tcp") || cfg.GetBool("parent-tls") {
|
||
// err = InitParentTCP()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitParentTLS
|
||
// if cfg.GetBool("parent-tls") {
|
||
// err = InitParentTLS()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// //InitParentUDP
|
||
// if cfg.GetBool("parent-udp") {
|
||
// err = InitParentUDP()
|
||
// }
|
||
// if err != nil {
|
||
// log.Fatalf("err : %s", err)
|
||
// }
|
||
// }
|
||
}
|
||
func main() {
|
||
err := initConfig()
|
||
if err != nil {
|
||
log.Fatalf("err : %s", err)
|
||
}
|
||
Clean(&service.S)
|
||
}
|
||
func Clean(s *services.Service) {
|
||
//block main()
|
||
signalChan := make(chan os.Signal, 1)
|
||
cleanupDone := make(chan bool)
|
||
signal.Notify(signalChan,
|
||
os.Interrupt,
|
||
syscall.SIGHUP,
|
||
syscall.SIGINT,
|
||
syscall.SIGTERM,
|
||
syscall.SIGQUIT)
|
||
go func() {
|
||
for _ = range signalChan {
|
||
fmt.Println("\nReceived an interrupt, stopping services...")
|
||
(*s).Clean()
|
||
cleanupDone <- true
|
||
}
|
||
}()
|
||
<-cleanupDone
|
||
}
|
||
|
||
// func Init() (err error) {
|
||
// return
|
||
// }
|
||
// func InitTCP() (err error) {
|
||
// return
|
||
// }
|
||
// func InitTLS() (err error) {
|
||
// certBytes, err = ioutil.ReadFile(cfg.GetString("cert"))
|
||
// if err != nil {
|
||
// log.Printf("err : %s", err)
|
||
// return
|
||
// }
|
||
// keyBytes, err = ioutil.ReadFile(cfg.GetString("key"))
|
||
// if err != nil {
|
||
// log.Printf("err : %s", err)
|
||
// return
|
||
// }
|
||
// return
|
||
// }
|
||
// func InitUDP() (err error) {
|
||
// return
|
||
// }
|
||
// func InitLocal() (err error) {
|
||
// return
|
||
// }
|
||
// func InitLocalTCP() (err error) {
|
||
// return
|
||
// }
|
||
// func InitLocalTLS() (err error) {
|
||
|
||
// return
|
||
// }
|
||
// func InitLocalHTTP() (err error) {
|
||
// err = InitBasicAuth()
|
||
// if err != nil {
|
||
// return
|
||
// }
|
||
// return
|
||
// }
|
||
|
||
// func InitLocalUDP() (err error) {
|
||
// return
|
||
// }
|
||
// func InitParent() (err error) {
|
||
// initOutPool(cfg.GetBool("parent-tls"), certBytes, keyBytes, cfg.GetString("parent"), cfg.GetInt("tcp-timeout"), cfg.GetInt("pool-size"), cfg.GetInt("pool-size")*2)
|
||
// checker = NewChecker(cfg.GetInt("check-timeout"), int64(cfg.GetInt("check-interval")), cfg.GetString("blocked"), cfg.GetString("direct"))
|
||
// log.Printf("use parent proxy : %s, udp : %v, tcp : %v, tls: %v", cfg.GetString("parent"), cfg.GetBool("parent-udp"), cfg.GetBool("parent-tcp"), cfg.GetBool("parent-tls"))
|
||
// return
|
||
// }
|
||
// func InitParentTCP() (err error) {
|
||
// return
|
||
// }
|
||
// func InitParentTLS() (err error) {
|
||
// return
|
||
// }
|
||
// func InitParentUDP() (err error) {
|
||
// return
|
||
// }
|
||
// func main() {
|
||
// //catch panic error
|
||
// defer func() {
|
||
// e := recover()
|
||
// if e != nil {
|
||
// log.Printf("err : %s,\ntrace:%s", e, string(debug.Stack()))
|
||
// }
|
||
// }()
|
||
// return
|
||
// sc := NewServerChannel(cfg.GetString("ip"), cfg.GetInt("port"))
|
||
// if cfg.GetBool("local-tls") {
|
||
// LocalTLSServer(&sc)
|
||
// } else if cfg.GetBool("local-tcp") {
|
||
// LocalTCPServer(&sc)
|
||
// } else if cfg.GetBool("local-udp") {
|
||
// LocalUDPServer(&sc)
|
||
// }
|
||
// log.Printf("proxy on %s , udp: %v, tcp: %v, tls: %v ,http: %v", (*sc.Listener).Addr(), cfg.GetBool("local-udp"), cfg.GetBool("local-tcp"), cfg.GetBool("local-tls"), cfg.GetBool("local-http"))
|
||
|
||
// clean()
|
||
// }
|
||
|
||
// func CheckTCPDeocder(inConn *net.Conn) (useProxy bool, address string, req *HTTPRequest, err error) {
|
||
// if cfg.GetBool("local-http") {
|
||
// useProxy, req, err = HTTPProxyDecoder(inConn)
|
||
// if err != nil {
|
||
// return
|
||
// }
|
||
// address = req.Host
|
||
// } else {
|
||
// address = cfg.GetString("parent")
|
||
// }
|
||
// if address == "" {
|
||
// useProxy = false
|
||
// } else if cfg.GetBool("always") {
|
||
// useProxy = true
|
||
// }
|
||
// return
|
||
// }
|
||
// func LocalTCPServer(sc *ServerChannel) {
|
||
// (*sc).ListenTCP(func(inConn net.Conn) {
|
||
// userProxy, address, req, err := CheckTCPDeocder(&inConn)
|
||
// if err != nil {
|
||
// if err != io.EOF {
|
||
// log.Printf("tcp decode error , ERR:%s", err)
|
||
// }
|
||
// return
|
||
// }
|
||
// TCPOutBridge(&inConn, userProxy, address, req)
|
||
// })
|
||
// }
|
||
|
||
// func LocalTLSServer(sc *ServerChannel) {
|
||
// (*sc).ListenTls(certBytes, keyBytes, func(inConn net.Conn) {
|
||
// userProxy, address, req, err := CheckTCPDeocder(&inConn)
|
||
// if err != nil {
|
||
// if err != io.EOF {
|
||
// log.Printf("tls decode error , ERR:%s", err)
|
||
// }
|
||
// return
|
||
// }
|
||
// TCPOutBridge(&inConn, userProxy, address, req)
|
||
// })
|
||
// }
|
||
|
||
// func LocalUDPServer(sc *ServerChannel) {
|
||
// (*sc).ListenUDP(func(packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
||
|
||
// })
|
||
// }
|
||
|
||
// func TCPOutBridge(inConn *net.Conn, userProxy bool, address string, req *HTTPRequest) {
|
||
// var outConn net.Conn
|
||
// var _outConn interface{}
|
||
// var err error
|
||
// if userProxy {
|
||
// _outConn, err = outPool.Get()
|
||
// if err == nil {
|
||
// outConn = _outConn.(net.Conn)
|
||
// }
|
||
// } else {
|
||
// outConn, err = ConnectHost(address, cfg.GetInt("tcp-timeout"))
|
||
// }
|
||
// if err != nil {
|
||
// log.Printf("connect to %s , err:%s", address, err)
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// inAddr := (*inConn).RemoteAddr().String()
|
||
// outAddr := outConn.RemoteAddr().String()
|
||
// log.Printf("%s use proxy %v", address, userProxy)
|
||
|
||
// if req != nil {
|
||
// if req.IsHTTPS() && !userProxy {
|
||
// req.HTTPSReply()
|
||
// } else {
|
||
// outConn.Write(req.headBuf)
|
||
// }
|
||
// }
|
||
|
||
// IoBind(*inConn, outConn, func(err error) {
|
||
// log.Printf("conn %s - %s [%s] released", inAddr, outAddr, address)
|
||
// closeConn(inConn)
|
||
// closeConn(&outConn)
|
||
// }, func(n int, d bool) {}, 0)
|
||
// log.Printf("conn %s - %s [%s] connected", inAddr, outAddr, address)
|
||
// }
|
||
// func UDPOutBridge() {
|
||
|
||
// }
|
||
|
||
// func DoUDP() {
|
||
// if cfg.GetBool("local-udp") {
|
||
|
||
// } else {
|
||
|
||
// }
|
||
// }
|
||
|
||
// //DoTCP contains tcp && http
|
||
// func DoTCP() {
|
||
// //define command line args
|
||
// proxyIsTls = cfg.GetBool("parent-tls")
|
||
// localIsTls = cfg.GetBool("local-tls")
|
||
// proxyAddr = cfg.GetString("parent")
|
||
// bindIP := cfg.GetString("ip")
|
||
// bindPort := cfg.GetInt("port")
|
||
// timeout := cfg.GetInt("check-timeout")
|
||
// connTimeout = cfg.GetInt("tcp-timeout")
|
||
// interval := cfg.GetInt("check-interval")
|
||
// certFile := cfg.GetString("cert")
|
||
// keyFile := cfg.GetString("key")
|
||
// blockedFile := cfg.GetString("blocked")
|
||
// directFile := cfg.GetString("direct")
|
||
|
||
// isTCP = cfg.GetBool("tcp")
|
||
// poolInitSize := cfg.GetInt("pool-size")
|
||
|
||
// //check args required
|
||
// if proxyIsTls && proxyAddr == "" {
|
||
// log.Fatalf("parent proxy address required")
|
||
// }
|
||
|
||
// //check tls cert&key file
|
||
// if certFile == "" {
|
||
// certFile = "proxy.crt"
|
||
// }
|
||
// if keyFile == "" {
|
||
// keyFile = "proxy.key"
|
||
// }
|
||
// if proxyIsTls || localIsTls {
|
||
// certBytes, err = ioutil.ReadFile(certFile)
|
||
// if err != nil {
|
||
// log.Printf("err : %s", err)
|
||
// return
|
||
// }
|
||
// keyBytes, err = ioutil.ReadFile(keyFile)
|
||
// if err != nil {
|
||
// log.Printf("err : %s", err)
|
||
// return
|
||
// }
|
||
// }
|
||
// //init tls info string
|
||
// var proxyIsTlsStr string
|
||
// var localIsTlsStr string
|
||
// protocolStr := "tcp"
|
||
// if !isTCP {
|
||
// protocolStr = "http(s)"
|
||
// }
|
||
// if proxyIsTls {
|
||
// proxyIsTlsStr = "tls "
|
||
// }
|
||
// if localIsTls {
|
||
// localIsTlsStr = "tls "
|
||
// }
|
||
// //init checker and pool if needed
|
||
// if proxyAddr != "" {
|
||
// if !isTCP && !cfg.GetBool("always") {
|
||
// checker = NewChecker(timeout, int64(interval), blockedFile, directFile)
|
||
// }
|
||
// log.Printf("use %sparent %s proxy : %s", proxyIsTlsStr, protocolStr, proxyAddr)
|
||
// initOutPool(proxyIsTls, certBytes, keyBytes, proxyAddr, connTimeout, poolInitSize, poolInitSize*2)
|
||
// } else if isTCP {
|
||
// log.Printf("tcp proxy need parent")
|
||
// return
|
||
// }
|
||
// //init basic auth only in http mode
|
||
// if !isTCP {
|
||
// basicAuth = NewBasicAuth()
|
||
// if cfg.GetString("auth-file") != "" {
|
||
// httpAuthorization = true
|
||
// n, err := basicAuth.AddFromFile(cfg.GetString("auth-file"))
|
||
// if err != nil {
|
||
// log.Fatalf("auth-file:%s", err)
|
||
// }
|
||
// log.Printf("auth data added from file %d , total:%d", n, basicAuth.Total())
|
||
// }
|
||
// if len(cfg.GetStringSlice("auth")) > 0 {
|
||
// httpAuthorization = true
|
||
// n := basicAuth.Add(cfg.GetStringSlice("auth"))
|
||
// log.Printf("auth data added %d, total:%d", n, basicAuth.Total())
|
||
// }
|
||
// }
|
||
|
||
// //listen
|
||
// sc := NewServerChannel(bindIP, bindPort)
|
||
// var err error
|
||
// if localIsTls {
|
||
// err = sc.ListenTls(certBytes, keyBytes, connHandler)
|
||
// } else {
|
||
// err = sc.ListenTCP(connHandler)
|
||
// }
|
||
// //listen fail
|
||
// if err != nil {
|
||
// log.Fatalf("ERR:%s", err)
|
||
// } else {
|
||
// log.Printf("%s %sproxy on %s", protocolStr, localIsTlsStr, (*sc.Listener).Addr())
|
||
// }
|
||
// }
|
||
// func connHandler(inConn net.Conn) {
|
||
// defer func() {
|
||
// err := recover()
|
||
// if err != nil {
|
||
// log.Printf("connHandler crashed,err:%s\nstack:%s", err, string(debug.Stack()))
|
||
// closeConn(&inConn)
|
||
// }
|
||
// }()
|
||
// if isTCP {
|
||
// tcpHandler(&inConn)
|
||
// } else {
|
||
// httpHandler(&inConn)
|
||
// }
|
||
// }
|
||
|
||
// func tcpHandler(inConn *net.Conn) {
|
||
// var outConn net.Conn
|
||
// var _outConn interface{}
|
||
// _outConn, err = outPool.Get()
|
||
// if err != nil {
|
||
// log.Printf("connect to %s , err:%s", proxyAddr, err)
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// outConn = _outConn.(net.Conn)
|
||
// inAddr := (*inConn).RemoteAddr().String()
|
||
// outAddr := outConn.RemoteAddr().String()
|
||
// IoBind((*inConn), outConn, func(err error) {
|
||
// log.Printf("conn %s - %s released", inAddr, outAddr)
|
||
// closeConn(inConn)
|
||
// closeConn(&outConn)
|
||
// }, func(n int, d bool) {}, 0)
|
||
// log.Printf("conn %s - %s connected", inAddr, outAddr)
|
||
// }
|
||
// func httpHandler(inConn *net.Conn) {
|
||
// var b [4096]byte
|
||
// var n int
|
||
// n, err = (*inConn).Read(b[:])
|
||
// if err != nil {
|
||
// if err != io.EOF {
|
||
// log.Printf("read err:%s", err)
|
||
// }
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// var method, host, address string
|
||
// index := bytes.IndexByte(b[:], '\n')
|
||
// if index == -1 {
|
||
// log.Printf("data err:%s", string(b[:n])[:50])
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
|
||
// fmt.Sscanf(string(b[:index]), "%s%s", &method, &host)
|
||
// if method == "" || host == "" {
|
||
// log.Printf("data err:%s", string(b[:n])[:50])
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// isHTTPS := method == "CONNECT"
|
||
|
||
// //http basic auth,only http
|
||
// if !isHTTPS {
|
||
// if httpAuthorization {
|
||
// //log.Printf("request :%s", string(b[:n]))
|
||
// authorization, err := getHeader("Authorization", b[:n])
|
||
// if err != nil {
|
||
// fmt.Fprint(*inConn, "HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"\"\r\n\r\nUnauthorized")
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// //log.Printf("Authorization:%s", authorization)
|
||
// basic := strings.Fields(authorization)
|
||
// if len(basic) != 2 {
|
||
// log.Printf("authorization data error,ERR:%s", authorization)
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// user, err := base64.StdEncoding.DecodeString(basic[1])
|
||
// if err != nil {
|
||
// log.Printf("authorization data parse error,ERR:%s", err)
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// authOk := basicAuth.Check(string(user))
|
||
// //log.Printf("auth %s,%v", string(user), authOk)
|
||
// if !authOk {
|
||
// fmt.Fprint(*inConn, "HTTP/1.1 401 Unauthorized\r\n\r\nUnauthorized")
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// var bytes []byte
|
||
// if isHTTPS { //https访问
|
||
// // [dd:dafds:fsd:dasd:2.2.23.3] or 2.2.23.3 or [dd:dafds:fsd:dasd:2.2.23.3]:2323 or 2.2.23.3:1234
|
||
// address = fixHost(host)
|
||
// if hostIsNoPort(host) { //host不带端口, 默认443
|
||
// address = address + ":443"
|
||
// }
|
||
// } else { //http访问
|
||
// hostPortURL, err := url.Parse(host)
|
||
// if err != nil {
|
||
// log.Printf("url.Parse %s ERR:%s", host, err)
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// _host := fixHost(hostPortURL.Host)
|
||
// address = _host
|
||
// if hostIsNoPort(_host) { //host不带端口, 默认80
|
||
// address = _host + ":80"
|
||
// }
|
||
// if _host != hostPortURL.Host {
|
||
// bytes = []byte(strings.Replace(string(b[:n]), hostPortURL.Host, _host, 1))
|
||
// host = strings.Replace(host, hostPortURL.Host, _host, 1)
|
||
// }
|
||
// }
|
||
// //get url , reslut host is the full url
|
||
// host, err = getURL(b[:n], host)
|
||
// // log.Printf("body:%s", string(b[:n]))
|
||
// // log.Printf("%s:%s", method, host)
|
||
// if err != nil {
|
||
// log.Printf("header data err:%s", err)
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
|
||
// useProxy := false
|
||
// if proxyAddr != "" {
|
||
// if cfg.GetBool("always") {
|
||
// useProxy = true
|
||
// } else {
|
||
// if isHTTPS {
|
||
// checker.Add(address, true, method, "", nil)
|
||
// } else {
|
||
// if bytes != nil {
|
||
// checker.Add(address, false, method, host, bytes)
|
||
// } else {
|
||
// checker.Add(address, false, method, host, b[:n])
|
||
// }
|
||
// }
|
||
// useProxy, _, _ = checker.IsBlocked(address)
|
||
// }
|
||
// // var failN, successN uint
|
||
// // useProxy, failN, successN = checker.IsBlocked(address)
|
||
// //log.Printf("use proxy ? %s : %v ,fail:%d, success:%d", address, useProxy, failN, successN)
|
||
// //log.Printf("use proxy ? %s : %v", address, useProxy)
|
||
// }
|
||
|
||
// var outConn net.Conn
|
||
// var _outConn interface{}
|
||
// if useProxy {
|
||
// _outConn, err = outPool.Get()
|
||
// if err == nil {
|
||
// outConn = _outConn.(net.Conn)
|
||
// }
|
||
// } else {
|
||
// outConn, err = ConnectHost(address, connTimeout)
|
||
// }
|
||
// if err != nil {
|
||
// log.Printf("connect to %s , err:%s", address, err)
|
||
// closeConn(inConn)
|
||
// return
|
||
// }
|
||
// inAddr := (*inConn).RemoteAddr().String()
|
||
// outAddr := outConn.RemoteAddr().String()
|
||
|
||
// if isHTTPS {
|
||
// if useProxy {
|
||
// outConn.Write(b[:n])
|
||
// } else {
|
||
// fmt.Fprint(*inConn, "HTTP/1.1 200 Connection established\r\n\r\n")
|
||
// }
|
||
// } else {
|
||
// if bytes != nil {
|
||
// outConn.Write(bytes)
|
||
// } else {
|
||
// outConn.Write(b[:n])
|
||
// }
|
||
// }
|
||
// IoBind(*inConn, outConn, func(err error) {
|
||
// log.Printf("conn %s - %s [%s] released", inAddr, outAddr, address)
|
||
// closeConn(inConn)
|
||
// closeConn(&outConn)
|
||
// }, func(n int, d bool) {}, 0)
|
||
// log.Printf("conn %s - %s [%s] connected", inAddr, outAddr, address)
|
||
// }
|