lots of changes

- debugging issues (not resolved) attempting to move the main executable into the base directory, this did not solve the issue, keeping it here.  A main.go and the executable.
listener_client — the WSS client
- removed support for anything admin
- injected the domains from the claim
- domains are now included as initialDomains
- registration performans as normal but includes adding the domains to a map of domains, and a collection of domains on the connection.
- the system now supports look up fast in either direction, not sure if it will be needed.
- reads a chan during registration before allowing traffic, making sure all is well.
- registration returns a true on the channel if all is well.   If it is not, false.  Likely will add some text to pass back.

Connection
- added support for boolean channel
- support for initial domains in a slice, these are brought back from the JWT as a interface and then are type asserted into the map
- removed all the old timer sender dwell stuff as a POC for traffic counts.

ConnectionTable
- added support for domain announcement after the WSS is connection.  Not sure if we will need these.  They have not been implemented.
- I assume all domains are registered with JWT unless I hear differently which would require a new WSS session
- expanded NewTable constructor
- populating domains into the domain map, and into the connection slice.
- added support for removing domains when a connection is removed.
This commit is contained in:
Henry Camacho 2017-02-12 14:39:50 -06:00
parent a5450dd205
commit 07380af871
9 changed files with 199 additions and 50 deletions

View File

@ -5,6 +5,6 @@ import "git.daplie.com/Daplie/go-rvpn-server/rvpn/rvpnmain"
var run = rvpnmain.Run var run = rvpnmain.Run
func main() { func main() {
run() rvpnmain.Run()
} }

View File

@ -21,9 +21,7 @@ func LaunchClientListener(connectionTable *connection.Table, secretKey *string,
default: default:
http.Error(w, "Not Found", 404) http.Error(w, "Not Found", 404)
} }
}) })
s := &http.Server{ s := &http.Server{
@ -54,16 +52,10 @@ func handleConnectionWebSocket(connectionTable *connection.Table, w http.Respons
return return
} }
loginfo.Println("access_token valid") loginfo.Println("help access_token valid")
claims := result.Claims.(jwt.MapClaims) claims := result.Claims.(jwt.MapClaims)
loginfo.Println("processing domains", claims["domains"]) domains, ok := claims["domains"].([]interface{})
if admin == true {
loginfo.Println("Recognized Admin connection, waiting authentication")
} else {
loginfo.Println("Recognized connection, waiting authentication")
}
var upgrader = websocket.Upgrader{ var upgrader = websocket.Upgrader{
ReadBufferSize: 1024, ReadBufferSize: 1024,
@ -75,12 +67,18 @@ func handleConnectionWebSocket(connectionTable *connection.Table, w http.Respons
loginfo.Println("WebSocket upgrade failed", err) loginfo.Println("WebSocket upgrade failed", err)
return return
} }
loginfo.Println("before connection table") loginfo.Println("before connection table")
//connection := &connection.Connection{connectionTable: connectionTable, conn: conn, send: make(chan []byte, 256), source: r.RemoteAddr, admin: admin} newConnection := connection.NewConnection(connectionTable, conn, r.RemoteAddr, domains)
connectionTable.Register() <- newConnection
connection := connection.NewConnection(connectionTable, conn, r.RemoteAddr) ok = <-newConnection.CommCh()
connectionTable.Register() <- connection if !ok {
go connection.Writer() loginfo.Println("connection registration failed ", newConnection)
connection.Reader() return
}
loginfo.Println("connection registration accepted ", newConnection)
go newConnection.Writer()
newConnection.Reader()
loginfo.Println("connection closing")
} }

View File

@ -3,8 +3,6 @@ package connection
import ( import (
"encoding/hex" "encoding/hex"
"time"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
@ -31,10 +29,16 @@ type Connection struct {
// bytes out // bytes out
bytesOut int64 bytesOut int64
// communications channel between go routines
commCh chan bool
//initialDomains - a list of domains from the JWT
initialDomains []interface{}
} }
//NewConnection -- Constructor //NewConnection -- Constructor
func NewConnection(connectionTable *Table, conn *websocket.Conn, remoteAddress string) (p *Connection) { func NewConnection(connectionTable *Table, conn *websocket.Conn, remoteAddress string, initialDomains []interface{}) (p *Connection) {
p = new(Connection) p = new(Connection)
p.connectionTable = connectionTable p.connectionTable = connectionTable
p.conn = conn p.conn = conn
@ -42,6 +46,8 @@ func NewConnection(connectionTable *Table, conn *websocket.Conn, remoteAddress s
p.bytesIn = 0 p.bytesIn = 0
p.bytesOut = 0 p.bytesOut = 0
p.send = make(chan []byte, 256) p.send = make(chan []byte, 256)
p.commCh = make(chan bool)
p.initialDomains = initialDomains
return return
} }
@ -59,6 +65,11 @@ func (c *Connection) ConnectionTable() (table *Table) {
return return
} }
//CommCh -- Property
func (c *Connection) CommCh() chan bool {
return c.commCh
}
//Reader -- export the reader function //Reader -- export the reader function
func (c *Connection) Reader() { func (c *Connection) Reader() {
defer func() { defer func() {
@ -82,8 +93,6 @@ func (c *Connection) Reader() {
//Writer -- expoer the writer function //Writer -- expoer the writer function
func (c *Connection) Writer() { func (c *Connection) Writer() {
dwell := time.NewTicker(5 * time.Second)
loginfo.Println("activate timer", dwell)
defer func() { defer func() {
c.conn.Close() c.conn.Close()
}() }()
@ -105,18 +114,3 @@ func (c *Connection) Writer() {
} }
} }
} }
func (c *Connection) sender() {
dwell := time.NewTicker(5 * time.Second)
loginfo.Println("activate timer", dwell)
defer func() {
c.conn.Close()
}()
for {
select {
case <-dwell.C:
loginfo.Println("Dwell Activated")
c.send <- []byte("This is a test")
}
}
}

View File

@ -1,19 +1,32 @@
package connection package connection
import "fmt"
const (
initialDomains = 0
incrementDomains = 0
)
//Table maintains the set of connections //Table maintains the set of connections
type Table struct { type Table struct {
connections map[*Connection]bool connections map[*Connection][]string
domains map[string]*Connection
register chan *Connection register chan *Connection
unregister chan *Connection unregister chan *Connection
domainAnnounce chan *DomainMapping
domainRevoke chan *DomainMapping
} }
//NewTable -- consructor //NewTable -- consructor
func NewTable() *Table { func NewTable() (p *Table) {
return &Table{ p = new(Table)
register: make(chan *Connection), p.connections = make(map[*Connection][]string)
unregister: make(chan *Connection), p.domains = make(map[string]*Connection)
connections: make(map[*Connection]bool), p.register = make(chan *Connection)
} p.unregister = make(chan *Connection)
p.domainAnnounce = make(chan *DomainMapping)
p.domainRevoke = make(chan *DomainMapping)
return
} }
//Run -- Execute //Run -- Execute
@ -23,19 +36,54 @@ func (c *Table) Run() {
select { select {
case connection := <-c.register: case connection := <-c.register:
loginfo.Println("register fired") loginfo.Println("register fired")
c.connections[connection] = true c.connections[connection] = make([]string, incrementDomains)
connection.commCh <- true
for conn := range c.connections { // handle initial domain additions
loginfo.Println(conn) for _, domain := range connection.initialDomains {
// add to the domains regirstation
newDomain := string(domain.(string))
loginfo.Println("adding domain ", newDomain, " to connection ", connection)
c.domains[newDomain] = connection
// add to the connection domain list
s := c.connections[connection]
c.connections[connection] = append(s, newDomain)
} }
fmt.Println(c.domains)
fmt.Println(c.connections)
loginfo.Println("register exiting")
case connection := <-c.unregister: case connection := <-c.unregister:
loginfo.Println("closing connection ", connection) loginfo.Println("closing connection ", connection)
if _, ok := c.connections[connection]; ok { if _, ok := c.connections[connection]; ok {
for _, domain := range c.connections[connection] {
fmt.Println("removing domain ", domain)
if _, ok := c.domains[domain]; ok {
delete(c.domains, domain)
}
}
delete(c.connections, connection) delete(c.connections, connection)
close(connection.send) close(connection.send)
fmt.Println(c.domains)
fmt.Println(c.connections)
} }
case domainMapping := <-c.domainAnnounce:
loginfo.Println("domainMapping fired ", domainMapping)
//check to make sure connection is already regiered, you can no register a domain without an apporved connection
//if connection, ok := connections[domainMapping.connection]; ok {
//} else {
//}
} }
} }
} }

View File

@ -0,0 +1,24 @@
package connection
//DomainMapping --
type DomainMapping struct {
connection *Connection
domainName string
err int
connCh chan bool
}
//ConnCh -- Property
func (c *DomainMapping) ConnCh() chan bool {
return c.connCh
}
//NewDomainMapping -- Constructor
func NewDomainMapping(connection *Connection, domain string) (p *DomainMapping) {
p = new(DomainMapping)
p.connection = connection
p.domainName = domain
p.err = -1
p.connCh = make(chan bool)
return
}

View File

@ -7,7 +7,7 @@ import (
"net/http/httputil" "net/http/httputil"
) )
//launchWebRequestListener - starts up extern http listeners, gets request and prep's to hand it off inside. //LaunchWebRequestExternalListener - starts up extern http listeners, gets request and prep's to hand it off inside.
func LaunchWebRequestExternalListener(serverBinding *string) { func LaunchWebRequestExternalListener(serverBinding *string) {
loginfo.Println("starting WebRequestExternal Listener ", *serverBinding) loginfo.Println("starting WebRequestExternal Listener ", *serverBinding)

View File

@ -11,6 +11,7 @@ import (
"git.daplie.com/Daplie/go-rvpn-server/rvpn/connection" "git.daplie.com/Daplie/go-rvpn-server/rvpn/connection"
"git.daplie.com/Daplie/go-rvpn-server/rvpn/external" "git.daplie.com/Daplie/go-rvpn-server/rvpn/external"
"git.daplie.com/Daplie/go-rvpn-server/rvpn/packer" "git.daplie.com/Daplie/go-rvpn-server/rvpn/packer"
"git.daplie.com/Daplie/go-rvpn-server/rvpn/xlate"
) )
var ( var (
@ -21,6 +22,7 @@ var (
argServerAdminBinding string argServerAdminBinding string
argServerExternalBinding string argServerExternalBinding string
connectionTable *connection.Table connectionTable *connection.Table
wssMapping *xlate.WssMapping
secretKey = "abc123" secretKey = "abc123"
) )
@ -53,6 +55,9 @@ func Run() {
loginfo.Println(p) loginfo.Println(p)
wssMapping = xlate.NewwssMapping()
go wssMapping.Run()
connectionTable = connection.NewTable() connectionTable = connection.NewTable()
go connectionTable.Run() go connectionTable.Run()
go client.LaunchClientListener(connectionTable, &secretKey, &argServerBinding) go client.LaunchClientListener(connectionTable, &secretKey, &argServerBinding)

17
rvpn/xlate/setup.go Normal file
View File

@ -0,0 +1,17 @@
package xlate
import (
"log"
"os"
)
var (
loginfo *log.Logger
logdebug *log.Logger
logFlags = log.Ldate | log.Lmicroseconds | log.Lshortfile
)
func init() {
loginfo = log.New(os.Stdout, "INFO: xlate: ", logFlags)
logdebug = log.New(os.Stdout, "DEBUG: xlate:", logFlags)
}

63
rvpn/xlate/wss_mapping.go Normal file
View File

@ -0,0 +1,63 @@
package xlate
import "golang.org/x/net/websocket"
const (
initialDomains = 10
incrementDomains = 10
)
type domain string
//WssRegistration --
type WssRegistration struct {
domainName domain
connection *websocket.Conn
}
//WssMapping --
type WssMapping struct {
register chan *websocket.Conn
unregister chan *websocket.Conn
domainRegister chan *WssRegistration
domainUnregister chan *WssRegistration
connections map[*websocket.Conn][]domain
domains map[domain]*websocket.Conn
}
//NewwssMapping -- constructor
func NewwssMapping() (p *WssMapping) {
p = new(WssMapping)
p.connections = make(map[*websocket.Conn][]domain)
return
}
//Run -- Execute
func (c *WssMapping) Run() {
loginfo.Println("WSSMapping starting")
for {
select {
case wssConn := <-c.register:
loginfo.Println("register fired")
c.connections[wssConn] = make([]domain, initialDomains)
for conn := range c.connections {
loginfo.Println(conn)
}
case wssConn := <-c.unregister:
loginfo.Println("closing connection ", wssConn)
if _, ok := c.connections[wssConn]; ok {
delete(c.connections, wssConn)
}
}
}
}
// register a wss connection first -- initialize the domain slice
// add a domain
// find the connectino add to the slice.
// find the domain set the connection in the map.
// domain(s) -> connection
// connection -> domains