From 07380af871b6b7fdedb23548df904c8c946cdf14 Mon Sep 17 00:00:00 2001 From: Henry Camacho Date: Sun, 12 Feb 2017 14:39:50 -0600 Subject: [PATCH] =?UTF-8?q?lots=20of=20changes=20-=20debugging=20issues=20?= =?UTF-8?q?(not=20resolved)=20attempting=20to=20move=20the=20main=20execut?= =?UTF-8?q?able=20into=20the=20base=20directory,=20this=20did=20not=20solv?= =?UTF-8?q?e=20the=20issue,=20keeping=20it=20here.=20=20A=20main.go=20and?= =?UTF-8?q?=20the=20executable.=20listener=5Fclient=20=E2=80=94=20the=20WS?= =?UTF-8?q?S=20client=20-=20removed=20support=20for=20anything=20admin=20-?= =?UTF-8?q?=20injected=20the=20domains=20from=20the=20claim=20-=20domains?= =?UTF-8?q?=20are=20now=20included=20as=20initialDomains=20-=20registratio?= =?UTF-8?q?n=20performans=20as=20normal=20but=20includes=20adding=20the=20?= =?UTF-8?q?domains=20to=20a=20map=20of=20domains,=20and=20a=20collection?= =?UTF-8?q?=20of=20domains=20on=20the=20connection.=20-=20the=20system=20n?= =?UTF-8?q?ow=20supports=20look=20up=20fast=20in=20either=20direction,=20n?= =?UTF-8?q?ot=20sure=20if=20it=20will=20be=20needed.=20-=20reads=20a=20cha?= =?UTF-8?q?n=20during=20registration=20before=20allowing=20traffic,=20maki?= =?UTF-8?q?ng=20sure=20all=20is=20well.=20-=20registration=20returns=20a?= =?UTF-8?q?=20true=20on=20the=20channel=20if=20all=20is=20well.=20=20=20If?= =?UTF-8?q?=20it=20is=20not,=20false.=20=20Likely=20will=20add=20some=20te?= =?UTF-8?q?xt=20to=20pass=20back.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- rvpn/main.go => main.go | 2 +- rvpn/client/listener_client.go | 30 ++++++------ rvpn/connection/connection.go | 34 ++++++------- rvpn/connection/connection_table.go | 72 +++++++++++++++++++++++----- rvpn/connection/domain_mapping.go | 24 ++++++++++ rvpn/external/listener_webrequest.go | 2 +- rvpn/rvpnmain/run.go | 5 ++ rvpn/xlate/setup.go | 17 +++++++ rvpn/xlate/wss_mapping.go | 63 ++++++++++++++++++++++++ 9 files changed, 199 insertions(+), 50 deletions(-) rename rvpn/main.go => main.go (87%) create mode 100644 rvpn/connection/domain_mapping.go create mode 100644 rvpn/xlate/setup.go create mode 100644 rvpn/xlate/wss_mapping.go diff --git a/rvpn/main.go b/main.go similarity index 87% rename from rvpn/main.go rename to main.go index 726300f..bbd429f 100644 --- a/rvpn/main.go +++ b/main.go @@ -5,6 +5,6 @@ import "git.daplie.com/Daplie/go-rvpn-server/rvpn/rvpnmain" var run = rvpnmain.Run func main() { - run() + rvpnmain.Run() } diff --git a/rvpn/client/listener_client.go b/rvpn/client/listener_client.go index 6b80334..f5afde6 100644 --- a/rvpn/client/listener_client.go +++ b/rvpn/client/listener_client.go @@ -21,9 +21,7 @@ func LaunchClientListener(connectionTable *connection.Table, secretKey *string, default: http.Error(w, "Not Found", 404) - } - }) s := &http.Server{ @@ -54,16 +52,10 @@ func handleConnectionWebSocket(connectionTable *connection.Table, w http.Respons return } - loginfo.Println("access_token valid") + loginfo.Println("help access_token valid") claims := result.Claims.(jwt.MapClaims) - loginfo.Println("processing domains", claims["domains"]) - - if admin == true { - loginfo.Println("Recognized Admin connection, waiting authentication") - } else { - loginfo.Println("Recognized connection, waiting authentication") - } + domains, ok := claims["domains"].([]interface{}) var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, @@ -75,12 +67,18 @@ func handleConnectionWebSocket(connectionTable *connection.Table, w http.Respons loginfo.Println("WebSocket upgrade failed", err) return } + loginfo.Println("before connection table") - //connection := &connection.Connection{connectionTable: connectionTable, conn: conn, send: make(chan []byte, 256), source: r.RemoteAddr, admin: admin} - - connection := connection.NewConnection(connectionTable, conn, r.RemoteAddr) - connectionTable.Register() <- connection - go connection.Writer() - connection.Reader() + newConnection := connection.NewConnection(connectionTable, conn, r.RemoteAddr, domains) + connectionTable.Register() <- newConnection + ok = <-newConnection.CommCh() + if !ok { + loginfo.Println("connection registration failed ", newConnection) + return + } + loginfo.Println("connection registration accepted ", newConnection) + go newConnection.Writer() + newConnection.Reader() + loginfo.Println("connection closing") } diff --git a/rvpn/connection/connection.go b/rvpn/connection/connection.go index 4d1322d..0a2fd15 100755 --- a/rvpn/connection/connection.go +++ b/rvpn/connection/connection.go @@ -3,8 +3,6 @@ package connection import ( "encoding/hex" - "time" - "github.com/gorilla/websocket" ) @@ -31,10 +29,16 @@ type Connection struct { // bytes out bytesOut int64 + + // communications channel between go routines + commCh chan bool + + //initialDomains - a list of domains from the JWT + initialDomains []interface{} } //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.connectionTable = connectionTable p.conn = conn @@ -42,6 +46,8 @@ func NewConnection(connectionTable *Table, conn *websocket.Conn, remoteAddress s p.bytesIn = 0 p.bytesOut = 0 p.send = make(chan []byte, 256) + p.commCh = make(chan bool) + p.initialDomains = initialDomains return } @@ -59,6 +65,11 @@ func (c *Connection) ConnectionTable() (table *Table) { return } +//CommCh -- Property +func (c *Connection) CommCh() chan bool { + return c.commCh +} + //Reader -- export the reader function func (c *Connection) Reader() { defer func() { @@ -82,8 +93,6 @@ func (c *Connection) Reader() { //Writer -- expoer the writer function func (c *Connection) Writer() { - dwell := time.NewTicker(5 * time.Second) - loginfo.Println("activate timer", dwell) defer func() { 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") - } - } -} diff --git a/rvpn/connection/connection_table.go b/rvpn/connection/connection_table.go index 9a5a29c..13dca92 100755 --- a/rvpn/connection/connection_table.go +++ b/rvpn/connection/connection_table.go @@ -1,19 +1,32 @@ package connection +import "fmt" + +const ( + initialDomains = 0 + incrementDomains = 0 +) + //Table maintains the set of connections type Table struct { - connections map[*Connection]bool - register chan *Connection - unregister chan *Connection + connections map[*Connection][]string + domains map[string]*Connection + register chan *Connection + unregister chan *Connection + domainAnnounce chan *DomainMapping + domainRevoke chan *DomainMapping } //NewTable -- consructor -func NewTable() *Table { - return &Table{ - register: make(chan *Connection), - unregister: make(chan *Connection), - connections: make(map[*Connection]bool), - } +func NewTable() (p *Table) { + p = new(Table) + p.connections = make(map[*Connection][]string) + p.domains = make(map[string]*Connection) + p.register = make(chan *Connection) + p.unregister = make(chan *Connection) + p.domainAnnounce = make(chan *DomainMapping) + p.domainRevoke = make(chan *DomainMapping) + return } //Run -- Execute @@ -23,19 +36,54 @@ func (c *Table) Run() { select { case connection := <-c.register: loginfo.Println("register fired") - c.connections[connection] = true + c.connections[connection] = make([]string, incrementDomains) + connection.commCh <- true - for conn := range c.connections { - loginfo.Println(conn) + // handle initial domain additions + 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: loginfo.Println("closing connection ", connection) 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) 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 { + + //} + } } } diff --git a/rvpn/connection/domain_mapping.go b/rvpn/connection/domain_mapping.go new file mode 100644 index 0000000..b2b349a --- /dev/null +++ b/rvpn/connection/domain_mapping.go @@ -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 +} diff --git a/rvpn/external/listener_webrequest.go b/rvpn/external/listener_webrequest.go index 3d130ea..61ab88c 100644 --- a/rvpn/external/listener_webrequest.go +++ b/rvpn/external/listener_webrequest.go @@ -7,7 +7,7 @@ import ( "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) { loginfo.Println("starting WebRequestExternal Listener ", *serverBinding) diff --git a/rvpn/rvpnmain/run.go b/rvpn/rvpnmain/run.go index 648b685..0e1560e 100644 --- a/rvpn/rvpnmain/run.go +++ b/rvpn/rvpnmain/run.go @@ -11,6 +11,7 @@ import ( "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/packer" + "git.daplie.com/Daplie/go-rvpn-server/rvpn/xlate" ) var ( @@ -21,6 +22,7 @@ var ( argServerAdminBinding string argServerExternalBinding string connectionTable *connection.Table + wssMapping *xlate.WssMapping secretKey = "abc123" ) @@ -53,6 +55,9 @@ func Run() { loginfo.Println(p) + wssMapping = xlate.NewwssMapping() + go wssMapping.Run() + connectionTable = connection.NewTable() go connectionTable.Run() go client.LaunchClientListener(connectionTable, &secretKey, &argServerBinding) diff --git a/rvpn/xlate/setup.go b/rvpn/xlate/setup.go new file mode 100644 index 0000000..fdc3c8e --- /dev/null +++ b/rvpn/xlate/setup.go @@ -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) +} \ No newline at end of file diff --git a/rvpn/xlate/wss_mapping.go b/rvpn/xlate/wss_mapping.go new file mode 100644 index 0000000..60b7d27 --- /dev/null +++ b/rvpn/xlate/wss_mapping.go @@ -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