Added support for YAML configuration file
- implemented viper module in code. - removed all the older configuration, not sure if we want to use flags or just the configuration files. - added support for dwell, idle and cancelceck timers - generic binding is now an int passing to the generic manager. - passing dwell, and idle directly to connection table. - adjusted all dead time structures, the system supports a map(string)interface{} of various dead time counters - this version also supports variable sized buffers for each request by using the bufio.reader - we peek all, and then pass everything down the channel we have. - I am wondering if this will be a problem is someone just starts pouring data down never ending. - direct support now for terminating domains - there is a domain for admin, and wss. Each shared the external address listener (testing 9999) Additions - added support for Discard for wedge connections - added support for ReadByte to wedge conn
This commit is contained in:
parent
2fc5cf5e69
commit
74591fd150
|
@ -0,0 +1,16 @@
|
|||
rvpn:
|
||||
wssdomain: localhost.daplie.me
|
||||
admindomain: rvpn.daplie.invalid
|
||||
genericlistener: 9999
|
||||
deadtime:
|
||||
dwell: 600
|
||||
idle: 60
|
||||
cancelcheck: 10
|
||||
domains:
|
||||
test.daplie.me:
|
||||
secret: abc123
|
||||
test2.daplie.me:
|
||||
secret: abc123
|
||||
test3.daplie.me:
|
||||
secret: abc123
|
||||
|
42
main.go
42
main.go
|
@ -8,6 +8,8 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"context"
|
||||
|
||||
"git.daplie.com/Daplie/go-rvpn-server/rvpn/genericlistener"
|
||||
|
@ -18,7 +20,7 @@ var (
|
|||
logdebug *log.Logger
|
||||
logFlags = log.Ldate | log.Lmicroseconds | log.Lshortfile
|
||||
argWssClientListener string
|
||||
argGenericBinding string
|
||||
argGenericBinding int
|
||||
argServerBinding string
|
||||
argServerAdminBinding string
|
||||
argServerExternalBinding string
|
||||
|
@ -26,25 +28,43 @@ var (
|
|||
connectionTable *genericlistener.Table
|
||||
secretKey = "abc123"
|
||||
wssHostName = "localhost.daplie.me"
|
||||
adminHostName = "rvpn.daplie.invalid"
|
||||
idle int
|
||||
dwell int
|
||||
cancelcheck int
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.IntVar(&argDeadTime, "dead-time-counter", 5, "deadtime counter in seconds")
|
||||
flag.StringVar(&argGenericBinding, "generic-listener", ":8443", "generic SSL Listener")
|
||||
flag.StringVar(&argWssClientListener, "wss-client-listener", ":3502", "wss client listener address:port")
|
||||
flag.StringVar(&argServerAdminBinding, "admin-server-port", "127.0.0.2:8000", "admin server Bind listener")
|
||||
flag.StringVar(&argServerExternalBinding, "external-server-port", "127.0.0.1:8080", "external server Bind listener")
|
||||
|
||||
}
|
||||
|
||||
//Main -- main entry point
|
||||
func main() {
|
||||
flag.Parse()
|
||||
loginfo = log.New(os.Stdout, "INFO: main: ", logFlags)
|
||||
logdebug = log.New(os.Stdout, "DEBUG: main:", logFlags)
|
||||
viper.SetConfigName("go-rvpn-server")
|
||||
viper.AddConfigPath("./")
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Fatal error config file: %s \n", err))
|
||||
}
|
||||
|
||||
loginfo = log.New(os.Stdout, "INFO: packer: ", logFlags)
|
||||
logdebug = log.New(os.Stdout, "DEBUG: packer:", logFlags)
|
||||
flag.IntVar(&argDeadTime, "dead-time-counter", 5, "deadtime counter in seconds")
|
||||
|
||||
wssHostName = viper.Get("rvpn.wssdomain").(string)
|
||||
adminHostName = viper.Get("rvpn.admindomain").(string)
|
||||
argGenericBinding = viper.GetInt("rvpn.genericlistener")
|
||||
deadtime := viper.Get("rvpn.deadtime")
|
||||
idle = deadtime.(map[string]interface{})["idle"].(int)
|
||||
dwell = deadtime.(map[string]interface{})["dwell"].(int)
|
||||
cancelcheck = deadtime.(map[string]interface{})["cancelcheck"].(int)
|
||||
|
||||
loginfo.Println("startup")
|
||||
|
||||
loginfo.Println(viper.Get("rvpn.genericlisteners"))
|
||||
loginfo.Println(viper.Get("rvpn.domains"))
|
||||
|
||||
fmt.Println("-=-=-=-=-=-=-=-=-=-=")
|
||||
|
||||
certbundle, err := tls.LoadX509KeyPair("certs/fullchain.pem", "certs/privkey.pem")
|
||||
|
@ -68,11 +88,11 @@ func main() {
|
|||
connectionTracking := genericlistener.NewTracking()
|
||||
go connectionTracking.Run(ctx)
|
||||
|
||||
connectionTable = genericlistener.NewTable()
|
||||
connectionTable = genericlistener.NewTable(dwell, idle)
|
||||
go connectionTable.Run(ctx)
|
||||
|
||||
genericListeners := genericlistener.NewGenerListeners(ctx, connectionTable, connectionTracking, secretKey, certbundle, argDeadTime, wssHostName)
|
||||
go genericListeners.Run(ctx, 9999)
|
||||
genericListeners := genericlistener.NewGenerListeners(ctx, connectionTable, connectionTracking, secretKey, certbundle, wssHostName, adminHostName, cancelcheck)
|
||||
go genericListeners.Run(ctx, argGenericBinding)
|
||||
|
||||
//Run for 10 minutes and then shutdown cleanly
|
||||
time.Sleep(600 * time.Second)
|
||||
|
|
|
@ -27,11 +27,21 @@ func NewWedgeConnSize(c net.Conn, size int) (p *WedgeConn) {
|
|||
return
|
||||
}
|
||||
|
||||
//Discard - discard a number of bytes, perhaps after peeking at the
|
||||
func (w *WedgeConn) Discard(n int) (discarded int, err error) {
|
||||
return w.reader.Discard(n)
|
||||
}
|
||||
|
||||
//Peek - Get a number of bytes outof the buffer, but allow the buffer to be replayed once read
|
||||
func (w *WedgeConn) Peek(n int) ([]byte, error) {
|
||||
return w.reader.Peek(n)
|
||||
}
|
||||
|
||||
//ReadByte -- A normal reader.
|
||||
func (w *WedgeConn) ReadByte() (byte, error) {
|
||||
return w.reader.ReadByte()
|
||||
}
|
||||
|
||||
//Read -- A normal reader.
|
||||
func (w *WedgeConn) Read(p []byte) (int, error) {
|
||||
cnt, err := w.reader.Read(p)
|
||||
|
|
|
@ -17,10 +17,12 @@ type Table struct {
|
|||
unregister chan *Connection
|
||||
domainAnnounce chan *DomainMapping
|
||||
domainRevoke chan *DomainMapping
|
||||
dwell int
|
||||
idle int
|
||||
}
|
||||
|
||||
//NewTable -- consructor
|
||||
func NewTable() (p *Table) {
|
||||
func NewTable(dwell int, idle int) (p *Table) {
|
||||
p = new(Table)
|
||||
p.connections = make(map[*Connection][]string)
|
||||
p.domains = make(map[string]*Connection)
|
||||
|
@ -28,6 +30,8 @@ func NewTable() (p *Table) {
|
|||
p.unregister = make(chan *Connection)
|
||||
p.domainAnnounce = make(chan *DomainMapping)
|
||||
p.domainRevoke = make(chan *DomainMapping)
|
||||
p.dwell = dwell
|
||||
p.idle = idle
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -66,7 +70,7 @@ func (c *Table) reaper(delay int, idle int) {
|
|||
func (c *Table) Run(ctx context.Context) {
|
||||
loginfo.Println("ConnectionTable starting")
|
||||
|
||||
go c.reaper(3000, 60)
|
||||
go c.reaper(c.dwell, c.idle)
|
||||
|
||||
for {
|
||||
select {
|
||||
|
|
|
@ -31,10 +31,11 @@ const (
|
|||
ctxSecretKey contextKey = "secretKey"
|
||||
ctxConnectionTable contextKey = "connectionTable"
|
||||
ctxConfig contextKey = "config"
|
||||
ctxDeadTime contextKey = "deadtime"
|
||||
ctxListenerRegistration contextKey = "listenerRegistration"
|
||||
ctxConnectionTrack contextKey = "connectionTrack"
|
||||
ctxWssHostName contextKey = "wsshostname"
|
||||
ctxAdminHostName contextKey = "adminHostName"
|
||||
ctxCancelCheck contextKey = "cancelcheck"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -52,11 +53,10 @@ const (
|
|||
// - if TLS, consume connection with TLS certbundle, pass to request identifier
|
||||
// - else, just pass to the request identififer
|
||||
func GenericListenAndServe(ctx context.Context, listenerRegistration *ListenerRegistration) {
|
||||
|
||||
loginfo.Println(":" + string(listenerRegistration.port))
|
||||
cancelCheck := ctx.Value(ctxCancelCheck).(int)
|
||||
|
||||
listenAddr, err := net.ResolveTCPAddr("tcp", ":"+strconv.Itoa(listenerRegistration.port))
|
||||
deadTime := ctx.Value(ctxDeadTime).(int)
|
||||
|
||||
if nil != err {
|
||||
loginfo.Println(err)
|
||||
|
@ -81,12 +81,10 @@ func GenericListenAndServe(ctx context.Context, listenerRegistration *ListenerRe
|
|||
loginfo.Println("Cancel signal hit")
|
||||
return
|
||||
default:
|
||||
ln.SetDeadline(time.Now().Add(time.Duration(deadTime) * time.Second))
|
||||
ln.SetDeadline(time.Now().Add(time.Duration(cancelCheck) * time.Second))
|
||||
|
||||
conn, err := ln.Accept()
|
||||
|
||||
loginfo.Println("Deadtime reached")
|
||||
|
||||
if nil != err {
|
||||
if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() {
|
||||
continue
|
||||
|
@ -160,6 +158,8 @@ func handleConnection(ctx context.Context, wConn *WedgeConn) {
|
|||
}
|
||||
|
||||
wssHostName := ctx.Value(ctxWssHostName).(string)
|
||||
adminHostName := ctx.Value(ctxAdminHostName).(string)
|
||||
|
||||
sniHostName, err := getHello(peek)
|
||||
if err != nil {
|
||||
loginfo.Println(err)
|
||||
|
@ -168,14 +168,8 @@ func handleConnection(ctx context.Context, wConn *WedgeConn) {
|
|||
|
||||
loginfo.Println("sni:", sniHostName)
|
||||
|
||||
if wssHostName != sniHostName {
|
||||
//traffic not terminating on the rvpn do not decrypt
|
||||
loginfo.Println("processing non terminating traffic")
|
||||
handleExternalHTTPRequest(ctx, wConn, sniHostName, "https")
|
||||
}
|
||||
|
||||
loginfo.Println("processing traffic terminating on RVPN")
|
||||
|
||||
if sniHostName == wssHostName {
|
||||
//handle WSS Path
|
||||
tlsListener := tls.NewListener(oneConn, config)
|
||||
|
||||
conn, err := tlsListener.Accept()
|
||||
|
@ -187,6 +181,26 @@ func handleConnection(ctx context.Context, wConn *WedgeConn) {
|
|||
tlsWedgeConn := NewWedgeConn(conn)
|
||||
handleStream(ctx, tlsWedgeConn)
|
||||
return
|
||||
|
||||
} else if sniHostName == adminHostName {
|
||||
// handle admin path
|
||||
tlsListener := tls.NewListener(oneConn, config)
|
||||
|
||||
conn, err := tlsListener.Accept()
|
||||
if err != nil {
|
||||
loginfo.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
tlsWedgeConn := NewWedgeConn(conn)
|
||||
handleStream(ctx, tlsWedgeConn)
|
||||
return
|
||||
|
||||
} else {
|
||||
//traffic not terminating on the rvpn do not decrypt
|
||||
loginfo.Println("processing non terminating traffic", wssHostName, sniHostName)
|
||||
handleExternalHTTPRequest(ctx, wConn, sniHostName, "https")
|
||||
}
|
||||
}
|
||||
|
||||
loginfo.Println("Handle Unencrypted")
|
||||
|
@ -257,7 +271,7 @@ func handleStream(ctx context.Context, wConn *WedgeConn) {
|
|||
|
||||
//handleExternalHTTPRequest -
|
||||
// - get a wConn and start processing requests
|
||||
func handleExternalHTTPRequest(ctx context.Context, extConn net.Conn, hostname string, service string) {
|
||||
func handleExternalHTTPRequest(ctx context.Context, extConn *WedgeConn, hostname string, service string) {
|
||||
connectionTracking := ctx.Value(ctxConnectionTrack).(*Tracking)
|
||||
|
||||
defer func() {
|
||||
|
@ -286,13 +300,17 @@ func handleExternalHTTPRequest(ctx context.Context, extConn net.Conn, hostname s
|
|||
return
|
||||
}
|
||||
|
||||
var buffer [1024]byte
|
||||
for {
|
||||
cnt, err := extConn.Read(buffer[0:])
|
||||
buffer, err := extConn.PeekAll()
|
||||
if err != nil {
|
||||
loginfo.Println("unable to peekAll", err)
|
||||
return
|
||||
}
|
||||
|
||||
loginfo.Println("Before Packer", hex.Dump(buffer))
|
||||
|
||||
cnt := len(buffer)
|
||||
|
||||
p := packer.NewPacker()
|
||||
p.Header.SetAddress(rAddr)
|
||||
p.Header.Port, err = strconv.Atoi(rPort)
|
||||
|
@ -309,6 +327,13 @@ func handleExternalHTTPRequest(ctx context.Context, extConn net.Conn, hostname s
|
|||
|
||||
sendTrack := NewSendTrack(buf.Bytes(), hostname)
|
||||
conn.SendCh() <- sendTrack
|
||||
|
||||
_, err = extConn.Discard(cnt)
|
||||
if err != nil {
|
||||
loginfo.Println("unable to discard", cnt, err)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,14 +51,15 @@ type GenericListeners struct {
|
|||
connectionTracking *Tracking
|
||||
secretKey string
|
||||
certbundle tls.Certificate
|
||||
deadTime int
|
||||
register chan *ListenerRegistration
|
||||
genericListeners *GenericListeners
|
||||
wssHostName string
|
||||
adminHostName string
|
||||
cancelCheck int
|
||||
}
|
||||
|
||||
//NewGenerListeners --
|
||||
func NewGenerListeners(ctx context.Context, connectionTable *Table, connectionTrack *Tracking, secretKey string, certbundle tls.Certificate, deadTime int, wssHostName string) (p *GenericListeners) {
|
||||
func NewGenerListeners(ctx context.Context, connectionTable *Table, connectionTrack *Tracking, secretKey string, certbundle tls.Certificate, wssHostName string, adminHostName string, cancelCheck int) (p *GenericListeners) {
|
||||
p = new(GenericListeners)
|
||||
p.listeners = make(map[*net.Listener]int)
|
||||
p.ctx = ctx
|
||||
|
@ -66,9 +67,10 @@ func NewGenerListeners(ctx context.Context, connectionTable *Table, connectionTr
|
|||
p.connectionTracking = connectionTrack
|
||||
p.secretKey = secretKey
|
||||
p.certbundle = certbundle
|
||||
p.deadTime = deadTime
|
||||
p.register = make(chan *ListenerRegistration)
|
||||
p.wssHostName = wssHostName
|
||||
p.adminHostName = adminHostName
|
||||
p.cancelCheck = cancelCheck
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -87,9 +89,10 @@ func (gl *GenericListeners) Run(ctx context.Context, initialPort int) {
|
|||
|
||||
ctx = context.WithValue(ctx, ctxConnectionTrack, gl.connectionTracking)
|
||||
ctx = context.WithValue(ctx, ctxConfig, config)
|
||||
ctx = context.WithValue(ctx, ctxDeadTime, gl.deadTime)
|
||||
ctx = context.WithValue(ctx, ctxListenerRegistration, gl.register)
|
||||
ctx = context.WithValue(ctx, ctxWssHostName, gl.wssHostName)
|
||||
ctx = context.WithValue(ctx, ctxAdminHostName, gl.adminHostName)
|
||||
ctx = context.WithValue(ctx, ctxCancelCheck, gl.cancelCheck)
|
||||
|
||||
go func(ctx context.Context) {
|
||||
for {
|
||||
|
|
Loading…
Reference in New Issue