heavier refactoring

This commit is contained in:
AJ ONeal 2020-04-30 04:43:36 -06:00
parent 09d296df2a
commit e740d2ca0f
14 changed files with 276 additions and 154 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
.env
.env.*
certs
*.exe
/telebitd

View File

@ -32,7 +32,12 @@ tmp $ serve-https -p 8080 -d /tmp --servername hfc.rootprojects.org --agree-tos
### Start Tunnel Client
```bash
node-tunnel-client $ bin/stunnel.js --locals http://hfc.rootprojects.org:8080,http://test1.hfc.rootprojects.org:8080 --stunneld wss://localhost.rootprojects.org:8443 --secret abc123
# For .env
TELEBIT_SECRET=abcdef1234567890
```
```bash
node-tunnel-client $ bin/stunnel.js --locals http://hfc.rootprojects.org:8080,http://test1.hfc.rootprojects.org:8080 --stunneld wss://localhost.rootprojects.org:8443 --secret abcdef1234567890
```
### Execute RVPN

View File

@ -8,46 +8,49 @@ import (
"io"
"io/ioutil"
"log"
"net/http"
"os"
"time"
telebit "git.coolaj86.com/coolaj86/go-telebitd"
"git.coolaj86.com/coolaj86/go-telebitd/relay"
"git.coolaj86.com/coolaj86/go-telebitd/server"
jwt "github.com/dgrijalva/jwt-go"
"github.com/spf13/viper"
lumberjack "gopkg.in/natefinch/lumberjack.v2"
telebit "git.coolaj86.com/coolaj86/go-telebitd"
"git.coolaj86.com/coolaj86/go-telebitd/server"
_ "github.com/joho/godotenv/autoload"
)
var (
logfile = "stdout"
configPath = "./"
configFile = "go-rvpn-server"
configFile = "telebit-relay"
loginfo *log.Logger
logdebug *log.Logger
logFlags = log.Ldate | log.Lmicroseconds | log.Lshortfile
argWssClientListener string
argGenericBinding int
tcpPort int
argServerBinding string
argServerAdminBinding string
argServerExternalBinding string
argDeadTime int
connectionTable *server.Table
secretKey = "abc123"
secretKey string
wssHostName = "localhost.rootprojects.org"
adminHostName = telebit.InvalidAdminDomain
idle int
dwell int
cancelcheck int
lbDefaultMethod string
serverName string
nickname string
)
func init() {
flag.StringVar(&logfile, "log", logfile, "Log file (or stdout/stderr; empty for none)")
flag.StringVar(&configPath, "config-path", configPath, "Configuration File Path")
flag.StringVar(&configFile, "config-file", configFile, "Configuration File Name")
flag.StringVar(&secretKey, "secret", "", "a >= 16-character random string for JWT key signing")
}
var logoutput io.Writer
@ -55,6 +58,15 @@ var logoutput io.Writer
//Main -- main entry point
func main() {
flag.Parse()
if "" == secretKey {
secretKey = os.Getenv("TELEBIT_SECRET")
}
if len(secretKey) < 16 {
fmt.Fprintf(os.Stderr, "Invalid secret: %q. See --help for details.\n", secretKey)
os.Exit(1)
}
switch logfile {
case "stdout":
logoutput = os.Stdout
@ -89,54 +101,51 @@ func main() {
wssHostName = viper.Get("rvpn.wssdomain").(string)
adminHostName = viper.Get("rvpn.admindomain").(string)
argGenericBinding = viper.GetInt("rvpn.genericlistener")
tcpPort = viper.GetInt("rvpn.port")
deadtime := viper.Get("rvpn.deadtime").(map[string]interface{})
idle = deadtime["idle"].(int)
dwell = deadtime["dwell"].(int)
cancelcheck = deadtime["cancelcheck"].(int)
lbDefaultMethod = viper.Get("rvpn.loadbalancing.defaultmethod").(string)
serverName = viper.Get("rvpn.serverName").(string)
nickname = viper.Get("rvpn.serverName").(string)
loginfo.Println("startup")
certbundle, err := tls.LoadX509KeyPair("certs/fullchain.pem", "certs/privkey.pem")
if err != nil {
loginfo.Println(err)
return
}
ctx, cancelContext := context.WithCancel(context.Background())
defer cancelContext()
serverStatus := server.NewStatus(ctx)
serverStatus.AdminDomain = adminHostName
serverStatus.WssDomain = wssHostName
serverStatus.Name = serverName
serverStatus.StartTime = time.Now()
serverStatus.Name = nickname
serverStatus.DeadTime = server.NewStatusDeadTime(dwell, idle, cancelcheck)
serverStatus.LoadbalanceDefaultMethod = lbDefaultMethod
// Setup for GenericListenServe.
// - establish context for the generic listener
// - startup listener
// - accept with peek buffer.
// - peek at the 1st 30 bytes.
// - check for tls
// - if tls, establish, protocol peek buffer, else decrypted
// - match protocol
connectionTable := server.NewTable(dwell, idle, lbDefaultMethod)
connectionTracking := server.NewTracking()
serverStatus.ConnectionTracking = connectionTracking
go connectionTracking.Run(ctx)
tlsConfig := &tls.Config{
GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
// TODO
// 1. call out to greenlock for validation
// 2. push challenges through http channel
// 3. receive certificates (or don't)
certbundle, err := tls.LoadX509KeyPair("certs/fullchain.pem", "certs/privkey.pem")
if err != nil {
return nil, err
}
return &certbundle, nil
},
}
connectionTable = server.NewTable(dwell, idle)
serverStatus.ConnectionTable = connectionTable
go connectionTable.Run(ctx, lbDefaultMethod)
authorizer := func(r *http.Request) (*server.Authz, error) {
// do we have a valid wss_client?
tokenString := r.URL.Query().Get("access_token")
_, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
return nil, err
}
genericListeners := server.NewGenerListeners(ctx, secretKey, certbundle, serverStatus)
//serverStatus.GenericListeners = genericListeners
go genericListeners.Run(ctx, argGenericBinding)
select {}
r := relay.New(ctx, tlsConfig, authorizer, serverStatus, connectionTable)
r.ListenAndServe(tcpPort)
}

1
go.mod
View File

@ -6,6 +6,7 @@ require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/gorilla/mux v1.7.4
github.com/gorilla/websocket v1.4.2
github.com/joho/godotenv v1.3.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.6.3
gopkg.in/natefinch/lumberjack.v2 v2.0.0

2
go.sum
View File

@ -49,6 +49,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=

52
relay/relay.go Normal file
View File

@ -0,0 +1,52 @@
package relay
import (
"context"
"crypto/tls"
"git.coolaj86.com/coolaj86/go-telebitd/server"
)
type Relay struct {
ctx context.Context
status *server.Status
mx *server.MPlexy
table *server.Table
}
func New(ctx context.Context, tlsConfig *tls.Config, authz server.Authorizer, status *server.Status, table *server.Table) *Relay {
return &Relay{
ctx: ctx,
status: status,
table: table,
mx: server.New(ctx, tlsConfig, authz, status),
}
}
func (r *Relay) ListenAndServe(port int) error {
serverStatus := r.status
// Setup for GenericListenServe.
// - establish context for the generic listener
// - startup listener
// - accept with peek buffer.
// - peek at the 1st 30 bytes.
// - check for tls
// - if tls, establish, protocol peek buffer, else decrypted
// - match protocol
connectionTracking := server.NewTracking()
serverStatus.ConnectionTracking = connectionTracking
go connectionTracking.Run(r.ctx)
serverStatus.ConnectionTable = r.table
go serverStatus.ConnectionTable.Run(r.ctx)
//serverStatus.GenericListeners = genericListeners
// blocks until it can listen, which it can't until started
go r.mx.MultiListenAndServe(port)
return r.mx.Run()
}

View File

@ -17,7 +17,7 @@ Docker version 17.03.0-ce, build 60ccb22
cd $GOPATH/src/git.coolaj86.com/coolaj86
git clone git@git.coolaj86.com:coolaj86/go-telebitd.git
cd go-rvpn-server
cd telebit-relay
go get
```
@ -36,7 +36,7 @@ Step 2/3 : LABEL maintainer "henry.f.camacho@gmail.com"
---> Running in 5cdffef8e33d
---> f7e09c097612
Removing intermediate container 5cdffef8e33d
Step 3/3 : WORKDIR "/go-rvpn-server"
Step 3/3 : WORKDIR "/telebit-relay"
---> 182aa9c814f2
Removing intermediate container f136550d6d48
Successfully built 182aa9c814f2

View File

@ -1,5 +1,5 @@
FROM golang:1.7.5
LABEL maintainer "henry.f.camacho@gmail.com"
FROM golang:1.14
LABEL maintainer "aj@therootcompany.com"
WORKDIR "/go-rvpn-server"
WORKDIR "/telebit-relay"

View File

@ -21,10 +21,11 @@ type Table struct {
domainRevoke chan *DomainMapping
dwell int
idle int
balanceMethod string
}
//NewTable -- consructor
func NewTable(dwell, idle int) (p *Table) {
func NewTable(dwell, idle int, balanceMethod string) (p *Table) {
p = new(Table)
p.connections = make(map[*Connection][]string)
p.domains = make(map[string]*DomainLoadBalance)
@ -34,6 +35,7 @@ func NewTable(dwell, idle int) (p *Table) {
p.domainRevoke = make(chan *DomainMapping)
p.dwell = dwell
p.idle = idle
p.balanceMethod = balanceMethod
return
}
@ -88,7 +90,7 @@ func (c *Table) GetConnection(serverID int64) (*Connection, error) {
}
//Run -- Execute
func (c *Table) Run(ctx context.Context, defaultMethod string) {
func (c *Table) Run(ctx context.Context) {
loginfo.Println("ConnectionTable starting")
go c.reaper(c.dwell, c.idle)
@ -122,7 +124,7 @@ func (c *Table) Run(ctx context.Context, defaultMethod string) {
c.domains[newDomain].AddConnection(connection)
} else {
//if not, then add as the 1st to the list of connections
c.domains[newDomain] = NewDomainLoadBalance(defaultMethod)
c.domains[newDomain] = NewDomainLoadBalance(c.balanceMethod)
c.domains[newDomain].AddConnection(connection)
}

View File

@ -6,6 +6,7 @@ import (
"context"
"crypto/tls"
"encoding/hex"
"fmt"
"log"
"net"
"net/http"
@ -31,7 +32,7 @@ const (
//ctxConnectionTable contextKey = "connectionTable"
ctxConfig contextKey = "config"
ctxConfig contextKey = "tlsConfig"
ctxListenerRegistration contextKey = "listenerRegistration"
ctxConnectionTrack contextKey = "connectionTrack"
ctxWssHostName contextKey = "wsshostname"
@ -40,21 +41,26 @@ const (
ctxLoadbalanceDefaultMethod contextKey = "lbdefaultmethod"
)
// TODO isn't this restriction in the TLS lib?
// or are we just pre-checking for remote hosts?
type tlsScheme int
const (
encryptNone int = iota
encryptNone tlsScheme = iota
encryptSSLV2
encryptSSLV3
encryptTLS10
encryptTLS11
encryptTLS12
encryptTLS13
)
//GenericListenAndServe -- used to lisen for any https traffic on 443 (8443)
// multiListenAndServe -- used to lisen for any https traffic on 443 (8443)
// - setup generic TCP listener, unencrypted TCP, with a Deadtime out
// - leaverage the wedgeConn to peek into the buffer.
// - 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) {
func (mx *MPlexy) multiListenAndServe(ctx context.Context, listenerRegistration *ListenerRegistration) {
loginfo.Println(":" + string(listenerRegistration.port))
cancelCheck := ctx.Value(ctxCancelCheck).(int)
@ -95,18 +101,24 @@ func GenericListenAndServe(ctx context.Context, listenerRegistration *ListenerRe
return
}
fmt.Println("New connection from %v on %v", conn.LocalAddr(), conn.RemoteAddr())
// TODO maybe put these into something like mx.newConnCh and have an mx.Accept()?
wedgeConn := NewWedgeConn(conn)
go acceptTCPOrTLS(ctx, wedgeConn)
go mx.accept(ctx, wedgeConn)
}
}
}
//acceptTCPOrTLS -
//accept -
// - accept a wedgeConnection along with all the other required attritvues
// - peek into the buffer, determine TLS or unencrypted
// - if TSL, then terminate with a TLS endpoint, pass to handleStream
// - if clearText, pass to handleStream
func acceptTCPOrTLS(ctx context.Context, wConn *WedgeConn) {
func (mx *MPlexy) accept(ctx context.Context, wConn *WedgeConn) {
// TODO shouldn't this responsibility fall elsewhere?
// (otherwise I think we're keeping this function in memory while something else fails to end)
// (i.e. something, somewhere is missing a `go doStuff()`
defer wConn.Close()
peekCnt := 10
@ -136,20 +148,24 @@ func acceptTCPOrTLS(ctx context.Context, wConn *WedgeConn) {
} else if bytes.Contains(peek[0:3], []byte{0x16, 0x03, 0x03}) {
encryptMode = encryptTLS12
} else if bytes.Contains(peek[0:3], []byte{0x16, 0x03, 0x04}) {
encryptMode = encryptTLS13
}
oneConn := &oneConnListener{wConn}
config := ctx.Value(ctxConfig).(*tls.Config)
tlsConfig := ctx.Value(ctxConfig).(*tls.Config)
if encryptMode == encryptSSLV2 {
loginfo.Println("SSLv2 is not accepted")
loginfo.Println("<= SSLv2 is not accepted")
return
}
if encryptMode == encryptNone {
loginfo.Println("Handle Unencrypted")
handleStream(ctx, wConn)
mx.handleStream(ctx, wConn)
return
}
@ -177,9 +193,10 @@ func acceptTCPOrTLS(ctx context.Context, wConn *WedgeConn) {
loginfo.Println("sni:", sniHostName)
// This is where a target device connects to receive traffic
if sniHostName == wssHostName {
//handle WSS Path
tlsListener := tls.NewListener(oneConn, config)
tlsListener := tls.NewListener(oneConn, tlsConfig)
conn, err := tlsListener.Accept()
if err != nil {
@ -188,30 +205,31 @@ func acceptTCPOrTLS(ctx context.Context, wConn *WedgeConn) {
}
tlsWedgeConn := NewWedgeConn(conn)
handleStream(ctx, tlsWedgeConn)
mx.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")
}
return
// This is where an admin of the relay manages it
if sniHostName == adminHostName {
// TODO mx.Admin.CheckRemoteIP(conn) here
// handle admin path
tlsListener := tls.NewListener(oneConn, tlsConfig)
conn, err := tlsListener.Accept()
if err != nil {
loginfo.Println(err)
return
}
tlsWedgeConn := NewWedgeConn(conn)
mx.handleStream(ctx, tlsWedgeConn)
return
}
//traffic not terminating on the rvpn do not decrypt
loginfo.Println("processing non terminating traffic", wssHostName, sniHostName)
handleExternalHTTPRequest(ctx, wConn, sniHostName, "https")
}
//handleStream --
@ -222,7 +240,7 @@ func acceptTCPOrTLS(ctx context.Context, wConn *WedgeConn) {
// - attempt to identify as ADMIN/API session
// - else handle as raw http
// - handle other?
func handleStream(ctx context.Context, wConn *WedgeConn) {
func (mx *MPlexy) handleStream(ctx context.Context, wConn *WedgeConn) {
loginfo.Println("handle Stream")
loginfo.Println("conn", wConn.LocalAddr().String(), wConn.RemoteAddr().String())
@ -234,6 +252,9 @@ func handleStream(ctx context.Context, wConn *WedgeConn) {
return
}
// TODO handle by TCP port as well
// (which needs a short read timeout since servers expect clients to say hello)
// HTTP Identifcation // CRLF
if !bytes.Contains(peek[:], []byte{0x0d, 0x0a}) {
return
@ -252,14 +273,11 @@ func handleStream(ctx context.Context, wConn *WedgeConn) {
return
}
// do we have a valid wss_client?
secretKey := ctx.Value(ctxSecretKey).(string)
tokenString := r.URL.Query().Get("access_token")
result, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
// TODO add newtypes
// TODO check if this is a websocket
_, err = mx.authorize(r)
if err == nil && result.Valid {
if err == nil {
loginfo.Println("Valid WSS dected...sending to handler")
oneConn := &oneConnListener{wConn}
handleWssClient(ctx, oneConn)
@ -268,6 +286,7 @@ func handleStream(ctx context.Context, wConn *WedgeConn) {
//if yes, prep the oneConn and send it to the handler
return
}
if strings.Contains(r.Host, telebit.InvalidAdminDomain) {
loginfo.Println("admin")
oneConn := &oneConnListener{wConn}

View File

@ -4,11 +4,28 @@ import (
"context"
"crypto/tls"
"net"
"net/http"
)
//ListenerRegistrationStatus - post registration status
type ListenerRegistrationStatus int
// Authz represents grants or privileges of a client
// clientID
// domains that may be forwarded
// # of domains that may be forwarded
// ports that may be forwarded (i.e. allow special ports < 1024, exclude 443, 25, etc)
// # of ports that may be forwarded
// # of concurrent conections
// # bandwith rate (i.e. 5 mbps)
// # bandwith cap per time period (i.e. 100 MB / hour)
// # throttled rate (i.e. 0 (kill), or 1 mbps)
type Authz struct {
}
// Authorizer is called when a new client connects and we need to know something about it
type Authorizer func(*http.Request) (*Authz, error)
const (
listenerAdded ListenerRegistrationStatus = iota
listenerExists
@ -40,99 +57,107 @@ func NewListenerRegistration(port int) (p *ListenerRegistration) {
p = new(ListenerRegistration)
p.port = port
p.commCh = make(chan *ListenerRegistration)
return
return p
}
// Servers -
type Servers struct {
// MPlexy -
type MPlexy struct {
listeners map[*net.Listener]int
ctx context.Context
connnectionTable *Table
connectionTracking *Tracking
secretKey string
certbundle tls.Certificate
authorize Authorizer
tlsConfig *tls.Config
register chan *ListenerRegistration
servers *Servers
wssHostName string
adminHostName string
cancelCheck int
lbDefaultMethod string
serverStatus *Status
//xservers *MPlexy
}
// NewGenerListeners creates tcp (and https and wss?) listeners
func NewGenerListeners(ctx context.Context, secretKey string, certbundle tls.Certificate, serverStatus *Status) (p *Servers) {
p = &Servers{}
p.listeners = make(map[*net.Listener]int)
p.ctx = ctx
p.connnectionTable = serverStatus.ConnectionTable
p.connectionTracking = serverStatus.ConnectionTracking
p.secretKey = secretKey
p.certbundle = certbundle
p.register = make(chan *ListenerRegistration)
p.wssHostName = serverStatus.WssDomain
p.adminHostName = serverStatus.AdminDomain
p.cancelCheck = serverStatus.DeadTime.cancelcheck
p.lbDefaultMethod = serverStatus.LoadbalanceDefaultMethod
p.serverStatus = serverStatus
return
// New creates tcp (and https and wss?) listeners
func New(ctx context.Context, tlsConfig *tls.Config, authz Authorizer, serverStatus *Status) (mx *MPlexy) {
mx = &MPlexy{
listeners: make(map[*net.Listener]int),
ctx: ctx,
connnectionTable: serverStatus.ConnectionTable,
connectionTracking: serverStatus.ConnectionTracking,
authorize: authz,
tlsConfig: tlsConfig,
register: make(chan *ListenerRegistration),
wssHostName: serverStatus.WssDomain,
adminHostName: serverStatus.AdminDomain,
cancelCheck: serverStatus.DeadTime.cancelcheck,
lbDefaultMethod: serverStatus.LoadbalanceDefaultMethod,
serverStatus: serverStatus,
}
return mx
}
//Run -- Execute
// - execute the GenericLister
// - pass initial port, we'll announce that
func (gl *Servers) Run(ctx context.Context, initialPort int) {
func (mx *MPlexy) Run() error {
loginfo.Println("ConnectionTable starting")
config := &tls.Config{Certificates: []tls.Certificate{gl.certbundle}}
loginfo.Println(mx.connectionTracking)
ctx = context.WithValue(ctx, ctxSecretKey, gl.secretKey)
ctx := mx.ctx
loginfo.Println(gl.connectionTracking)
// For just this bit
ctx = context.WithValue(ctx, ctxConnectionTrack, mx.connectionTracking)
ctx = context.WithValue(ctx, ctxConnectionTrack, gl.connectionTracking)
ctx = context.WithValue(ctx, ctxConfig, config)
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)
ctx = context.WithValue(ctx, ctxLoadbalanceDefaultMethod, gl.lbDefaultMethod)
ctx = context.WithValue(ctx, ctxServerStatus, gl.serverStatus)
// For all Listeners
ctx = context.WithValue(ctx, ctxConfig, mx.tlsConfig)
ctx = context.WithValue(ctx, ctxListenerRegistration, mx.register)
ctx = context.WithValue(ctx, ctxWssHostName, mx.wssHostName)
ctx = context.WithValue(ctx, ctxAdminHostName, mx.adminHostName)
ctx = context.WithValue(ctx, ctxCancelCheck, mx.cancelCheck)
ctx = context.WithValue(ctx, ctxLoadbalanceDefaultMethod, mx.lbDefaultMethod)
ctx = context.WithValue(ctx, ctxServerStatus, mx.serverStatus)
go func(ctx context.Context) {
for {
select {
for {
select {
case <-ctx.Done():
loginfo.Println("Cancel signal hit")
return
case <-ctx.Done():
loginfo.Println("Cancel signal hit")
return nil
case registration := <-gl.register:
loginfo.Println("register fired", registration.port)
case registration := <-mx.register:
loginfo.Println("register fired", registration.port)
// check to see if port is already running
for listener := range gl.listeners {
if gl.listeners[listener] == registration.port {
loginfo.Println("listener already running", registration.port)
registration.status = listenerExists
registration.commCh <- registration
}
}
loginfo.Println("listener starting up ", registration.port)
loginfo.Println(ctx.Value(ctxConnectionTrack).(*Tracking))
go GenericListenAndServe(ctx, registration)
status := <-registration.commCh
if status.status == listenerAdded {
gl.listeners[status.listener] = status.port
} else if status.status == listenerFault {
loginfo.Println("Unable to create a new listerer", registration.port)
// check to see if port is already running
for listener := range mx.listeners {
if mx.listeners[listener] == registration.port {
loginfo.Println("listener already running", registration.port)
registration.status = listenerExists
registration.commCh <- registration
}
}
loginfo.Println("listener starting up ", registration.port)
loginfo.Println(ctx.Value(ctxConnectionTrack).(*Tracking))
go mx.multiListenAndServe(ctx, registration)
status := <-registration.commCh
if status.status == listenerAdded {
mx.listeners[status.listener] = status.port
} else if status.status == listenerFault {
loginfo.Println("Unable to create a new listerer", registration.port)
}
}
}
}(ctx)
newListener := NewListenerRegistration(initialPort)
gl.register <- newListener
return nil
}
func (mx *MPlexy) Start() {
go mx.Run()
}
// MultiListenAndServe starts another listener (to the same application) on a new port
func (mx *MPlexy) MultiListenAndServe(port int) {
// TODO how to associate a listening device with a given plain port
mx.register <- NewListenerRegistration(port)
}

View File

@ -15,13 +15,13 @@ type Status struct {
DeadTime *StatusDeadTime
ConnectionTracking *Tracking
ConnectionTable *Table
servers *Servers
LoadbalanceDefaultMethod string
AdminStats *TrafficStats
AdminReqTyoe *AdminReqType
TrafficStats *TrafficStats
ExtConnections *ConnectionStats
WSSConnections *ConnectionStats
//servers *MPlexy
}
//NewStatus --
@ -32,7 +32,9 @@ func NewStatus(ctx context.Context) (p *Status) {
p.TrafficStats = new(TrafficStats)
p.ExtConnections = new(ConnectionStats)
p.WSSConnections = new(ConnectionStats)
return
// TODO any reason not to set StartTime like this?
p.StartTime = time.Now()
return p
}
// South Facing Functions

View File

@ -2,4 +2,7 @@ package telebit
// InvalidAdminDomain is a domain that can only be accessed by Domain Fronting
// (i.e. trixy clients sending fake headers), not browsers
var InvalidAdminDomain = "rvpn.rootprojects.invalid"
var InvalidAdminDomain = "chilly-bobcat-15.telebit.io"
//var InvalidAdminDomain = "invalid.rootprojects.org"
//var InvalidAdminDomain = "rvpn.rootprojects.invalid"