diff --git a/connection.go b/connection.go new file mode 100755 index 0000000..bbd02a9 --- /dev/null +++ b/connection.go @@ -0,0 +1,129 @@ +package main + +import ( + "log" + "net/http" + + "time" + + "github.com/gorilla/websocket" +) + +var upgrader = websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, +} + +// Connection track websocket and faciliates in and out data +type Connection struct { + connectionTable *ConnectionTable + + // The websocket connection. + conn *websocket.Conn + + // Buffered channel of outbound messages. + send chan []byte + + // Address of the Remote End Point + source string + + // admin flag. Grants access to admin features + admin bool + + // bytes in + bytesIn int64 + + // bytes out + bytesOut int64 +} + +func (c *Connection) addIn(num int64) { + c.bytesIn = c.bytesIn + num +} + +func (c *Connection) addOut(num int64) { + c.bytesOut = c.bytesOut + num +} + +func (c *Connection) reader() { + defer func() { + c.connectionTable.unregister <- c + c.conn.Close() + }() + c.conn.SetReadLimit(maxMessageSize) + for { + _, message, err := c.conn.ReadMessage() + if err != nil { + if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) { + log.Printf("error: %v", err) + } + break + } + loginfo.Println(message) + c.addIn(int64(len(message))) + + loginfo.Println(c) + } +} + +func (c *Connection) writer() { + dwell := time.NewTicker(5 * time.Second) + loginfo.Println("activate timer", dwell) + defer func() { + c.conn.Close() + }() + for { + select { + + case message := <-c.send: + w, err := c.conn.NextWriter(websocket.TextMessage) + if err != nil { + return + } + w.Write(message) + + if err := w.Close(); err != nil { + return + } + + c.addOut(int64(len(message))) + } + } +} + +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") + } + } +} + +// handleConnectionWebSocket handles websocket requests from the peer. +func handleConnectionWebSocket(connectionTable *ConnectionTable, w http.ResponseWriter, r *http.Request, admin bool) { + loginfo.Println("websocket opening ", r.RemoteAddr) + + if admin == true { + loginfo.Println("Recognized Admin connection, waiting authentication") + } else { + loginfo.Println("Recognized connection, waiting authentication") + } + + conn, err := upgrader.Upgrade(w, r, nil) + if err != nil { + loginfo.Println("WebSocket upgrade failed", err) + return + } + connection := &Connection{connectionTable: connectionTable, conn: conn, send: make(chan []byte, 256), source: r.RemoteAddr, admin: admin} + connection.connectionTable.register <- connection + go connection.writer() + go connection.sender() + connection.reader() +} diff --git a/connection_table.go b/connection_table.go new file mode 100755 index 0000000..cfa4e81 --- /dev/null +++ b/connection_table.go @@ -0,0 +1,37 @@ +package main + +// ConnectionTable maintains the set of connections +type ConnectionTable struct { + connections map[*Connection]bool + register chan *Connection + unregister chan *Connection +} + +func newConnectionTable() *ConnectionTable { + return &ConnectionTable{ + register: make(chan *Connection), + unregister: make(chan *Connection), + connections: make(map[*Connection]bool), + } +} + +func (c *ConnectionTable) run() { + loginfo.Println("ConnectionTable starting") + for { + select { + case connection := <-c.register: + loginfo.Println("register fired") + c.connections[connection] = true + + for conn := range c.connections { + loginfo.Println(conn) + } + + case connection := <-c.unregister: + if _, ok := c.connections[connection]; ok { + delete(c.connections, connection) + close(connection.send) + } + } + } +} diff --git a/go-rvpn-server b/go-rvpn-server new file mode 100755 index 0000000..02dc2a8 Binary files /dev/null and b/go-rvpn-server differ diff --git a/html/admin.html b/html/admin.html new file mode 100755 index 0000000..3f376e7 --- /dev/null +++ b/html/admin.html @@ -0,0 +1,110 @@ + + +
+{[{text}]}
+{[{text}]}
+