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