Implement tcp proxy with single forward
parent
698edf7e45
commit
8a90a3adda
|
|
@ -28,6 +28,13 @@ func GetRoutes() map[string]string {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetTCP() (string, bool) {
|
||||||
|
v := packable.NewString()
|
||||||
|
conf.Get(nsConf, flagTCP, v)
|
||||||
|
tcpAddr := v.String()
|
||||||
|
return tcpAddr, notEmpty(tcpAddr)
|
||||||
|
}
|
||||||
|
|
||||||
func GetSSL() (string, string, bool) {
|
func GetSSL() (string, string, bool) {
|
||||||
v := packable.NewString()
|
v := packable.NewString()
|
||||||
conf.Get(nsConf, flagCert, v)
|
conf.Get(nsConf, flagCert, v)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ const flagPort = "p"
|
||||||
const flagRoutes = "r"
|
const flagRoutes = "r"
|
||||||
const flagConf = "c"
|
const flagConf = "c"
|
||||||
const flagCert = "crt"
|
const flagCert = "crt"
|
||||||
|
const flagTCP = "tcp"
|
||||||
const flagKey = "key"
|
const flagKey = "key"
|
||||||
const flagUser = "user"
|
const flagUser = "user"
|
||||||
const flagPass = "pass"
|
const flagPass = "pass"
|
||||||
|
|
@ -36,6 +37,7 @@ type fileConf struct {
|
||||||
Port string `yaml:"p"`
|
Port string `yaml:"p"`
|
||||||
Routes []string `yaml:"r"`
|
Routes []string `yaml:"r"`
|
||||||
CertPath string `yaml:"crt"`
|
CertPath string `yaml:"crt"`
|
||||||
|
TCPPath string `yaml:"tcp"`
|
||||||
KeyPath string `yaml:"key"`
|
KeyPath string `yaml:"key"`
|
||||||
Username string `yaml:"user"`
|
Username string `yaml:"user"`
|
||||||
Password string `yaml:"pass"`
|
Password string `yaml:"pass"`
|
||||||
|
|
@ -85,6 +87,9 @@ func fromFile() error {
|
||||||
if err := conf.Set(nsConf, flagCert, packable.NewString(c.CertPath)); err != nil {
|
if err := conf.Set(nsConf, flagCert, packable.NewString(c.CertPath)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := conf.Set(nsConf, flagTCP, packable.NewString(c.TCPPath)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := conf.Set(nsConf, flagKey, packable.NewString(c.KeyPath)); err != nil {
|
if err := conf.Set(nsConf, flagKey, packable.NewString(c.KeyPath)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -115,6 +120,7 @@ func fromFlags() error {
|
||||||
binds = append(binds, addFlag(flagConf, "", "configuration file path"))
|
binds = append(binds, addFlag(flagConf, "", "configuration file path"))
|
||||||
binds = append(binds, addFlag(flagRoutes, "", "comma-separated routes to map, each as from:scheme://to.tld:port"))
|
binds = append(binds, addFlag(flagRoutes, "", "comma-separated routes to map, each as from:scheme://to.tld:port"))
|
||||||
binds = append(binds, addFlag(flagCert, "", "path to .crt"))
|
binds = append(binds, addFlag(flagCert, "", "path to .crt"))
|
||||||
|
binds = append(binds, addFlag(flagTCP, "", "tcp addr"))
|
||||||
binds = append(binds, addFlag(flagKey, "", "path to .key"))
|
binds = append(binds, addFlag(flagKey, "", "path to .key"))
|
||||||
binds = append(binds, addFlag(flagUser, "", "basic auth username"))
|
binds = append(binds, addFlag(flagUser, "", "basic auth username"))
|
||||||
binds = append(binds, addFlag(flagPass, "", "basic auth password"))
|
binds = append(binds, addFlag(flagPass, "", "basic auth password"))
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,12 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
"local/rproxy3/config"
|
"local/rproxy3/config"
|
||||||
"local/rproxy3/storage"
|
"local/rproxy3/storage"
|
||||||
"local/rproxy3/storage/packable"
|
"local/rproxy3/storage/packable"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -24,6 +26,7 @@ type listenerScheme int
|
||||||
const (
|
const (
|
||||||
schemeHTTP listenerScheme = iota
|
schemeHTTP listenerScheme = iota
|
||||||
schemeHTTPS listenerScheme = iota
|
schemeHTTPS listenerScheme = iota
|
||||||
|
schemeTCP listenerScheme = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ls listenerScheme) String() string {
|
func (ls listenerScheme) String() string {
|
||||||
|
|
@ -32,6 +35,8 @@ func (ls listenerScheme) String() string {
|
||||||
return "http"
|
return "http"
|
||||||
case schemeHTTPS:
|
case schemeHTTPS:
|
||||||
return "https"
|
return "https"
|
||||||
|
case schemeTCP:
|
||||||
|
return "tcp"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
@ -58,6 +63,9 @@ func (s *Server) Run() error {
|
||||||
if _, _, ok := config.GetSSL(); ok {
|
if _, _, ok := config.GetSSL(); ok {
|
||||||
scheme = schemeHTTPS
|
scheme = schemeHTTPS
|
||||||
}
|
}
|
||||||
|
if _, ok := config.GetTCP(); ok {
|
||||||
|
scheme = schemeTCP
|
||||||
|
}
|
||||||
log.Printf("Listening for %v on %v...\n", scheme, s.addr)
|
log.Printf("Listening for %v on %v...\n", scheme, s.addr)
|
||||||
switch scheme {
|
switch scheme {
|
||||||
case schemeHTTP:
|
case schemeHTTP:
|
||||||
|
|
@ -83,6 +91,10 @@ func (s *Server) Run() error {
|
||||||
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
|
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
|
||||||
}
|
}
|
||||||
return httpsServer.ListenAndServeTLS(c, k)
|
return httpsServer.ListenAndServeTLS(c, k)
|
||||||
|
case schemeTCP:
|
||||||
|
log.Printf("Serve tcp")
|
||||||
|
addr, _ := config.GetTCP()
|
||||||
|
return s.ServeTCP(addr)
|
||||||
}
|
}
|
||||||
return errors.New("did not load server")
|
return errors.New("did not load server")
|
||||||
}
|
}
|
||||||
|
|
@ -103,6 +115,36 @@ func (s *Server) doAuth(foo http.HandlerFunc) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) ServeTCP(addr string) error {
|
||||||
|
listen, err := net.Listen("tcp", s.addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
c, err := listen.Accept()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func(c net.Conn) {
|
||||||
|
d, err := net.Dial("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go pipe(c, d)
|
||||||
|
go pipe(d, c)
|
||||||
|
}(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func pipe(a, b net.Conn) {
|
||||||
|
log.Println("open pipe")
|
||||||
|
defer log.Println("close pipe")
|
||||||
|
defer a.Close()
|
||||||
|
defer b.Close()
|
||||||
|
io.Copy(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) Pre(foo http.HandlerFunc) http.HandlerFunc {
|
func (s *Server) Pre(foo http.HandlerFunc) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, can := context.WithTimeout(r.Context(), time.Second*time.Duration(config.GetTimeout()))
|
ctx, can := context.WithTimeout(r.Context(), time.Second*time.Duration(config.GetTimeout()))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue