diff --git a/README.md b/README.md index b6d0b0d..c4d0e3c 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ go get "github.com/gorilla/mux" - browse to https://127.0.0.2:8000/api/servers ```json -{"Servers":[{"ServerName":"0xc42005b110","Duration":42.342176121,"BytesIn":91,"BytesOut":3476}]} +{"Servers":[{"ServerName":"0xc420019500","Domains":[{"Domain":"127.0.0.1","BytesIn":0,"BytesOut":2607},{"Domain":"hfc.daplie.me","BytesIn":0,"BytesOut":0},{"Domain":"test.hfc.daplie.me","BytesIn":0,"BytesOut":0}],"Duration":372.34454292,"BytesIn":65,"BytesOut":2607}]} ``` -The above is telemetry from the RVPN server. +The above is telemetry from the RVPN server. (now supports domain byte tracking) Work is continuing, please review make sure it is what you are looking for. diff --git a/rvpn/admin/domain_api.go b/rvpn/admin/domain_api.go new file mode 100644 index 0000000..8813ee2 --- /dev/null +++ b/rvpn/admin/domain_api.go @@ -0,0 +1,29 @@ +package admin + +//DomainAPI -- Structure to hold the domain tracking for JSON +type DomainAPI struct { + Domain string + BytesIn int64 + BytesOut int64 +} + +//NewDomainAPI - Constructor +func NewDomainAPI(domain string, bytesin int64, bytesout int64) (d *DomainAPI) { + d = new(DomainAPI) + d.Domain = domain + d.BytesIn = bytesin + d.BytesOut = bytesout + return +} + +// //DomainAPIContainer -- +// type DomainAPIContainer struct { +// Domains []*DomainAPI +// } + +// //NewDomainAPIContainer -- Constructor +// func NewDomainAPIContainer() (p *DomainAPIContainer) { +// p = new(DomainAPIContainer) +// p.Domains = make([]*DomainAPI, 0) +// return p +// } diff --git a/rvpn/admin/listener_admin.go b/rvpn/admin/listener_admin.go index be141e4..eaef4e3 100644 --- a/rvpn/admin/listener_admin.go +++ b/rvpn/admin/listener_admin.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "net/http" - "time" "git.daplie.com/Daplie/go-rvpn-server/rvpn/connection" @@ -41,40 +40,6 @@ func index(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Welcome!") } -//ServerAPI -- Structure to support the server API -type ServerAPI struct { - ServerName string - Duration float64 - BytesIn int64 - BytesOut int64 -} - -//NewServerAPI - Constructor -func NewServerAPI(c *connection.Connection) (s *ServerAPI) { - s = new(ServerAPI) - s.ServerName = fmt.Sprintf("%p", c) - - fmt.Println(s.ServerName) - - s.Duration = time.Since(c.ConnectTime()).Seconds() - s.BytesIn = c.BytesIn() - s.BytesOut = c.BytesOut() - return - -} - -//ServerAPIContainer -- Holder for all the Servers -type ServerAPIContainer struct { - Servers []*ServerAPI -} - -//NewServerAPIContainer -- Constructor -func NewServerAPIContainer() (p *ServerAPIContainer) { - p = new(ServerAPIContainer) - p.Servers = make([]*ServerAPI, 0) - return p -} - func apiServers(w http.ResponseWriter, r *http.Request) { fmt.Println("here") serverContainer := NewServerAPIContainer() @@ -82,6 +47,7 @@ func apiServers(w http.ResponseWriter, r *http.Request) { for c := range connTable.Connections() { serverAPI := NewServerAPI(c) serverContainer.Servers = append(serverContainer.Servers, serverAPI) + } w.Header().Set("Content-Type", "application/json; charset=UTF-8") diff --git a/rvpn/admin/server_api.go b/rvpn/admin/server_api.go new file mode 100644 index 0000000..f95e350 --- /dev/null +++ b/rvpn/admin/server_api.go @@ -0,0 +1,46 @@ +package admin + +import ( + "fmt" + "time" + + "git.daplie.com/Daplie/go-rvpn-server/rvpn/connection" +) + +//ServerAPI -- Structure to support the server API +type ServerAPI struct { + ServerName string + Domains []*DomainAPI + Duration float64 + BytesIn int64 + BytesOut int64 +} + +//NewServerAPI - Constructor +func NewServerAPI(c *connection.Connection) (s *ServerAPI) { + s = new(ServerAPI) + s.ServerName = fmt.Sprintf("%p", c) + s.Domains = make([]*DomainAPI, 0) + s.Duration = time.Since(c.ConnectTime()).Seconds() + s.BytesIn = c.BytesIn() + s.BytesOut = c.BytesOut() + + for d := range c.DomainTrack { + dt := c.DomainTrack[d] + domainAPI := NewDomainAPI(dt.DomainName, dt.BytesIn(), dt.BytesOut()) + s.Domains = append(s.Domains, domainAPI) + } + return +} + +//ServerAPIContainer -- Holder for all the Servers +type ServerAPIContainer struct { + Servers []*ServerAPI +} + +//NewServerAPIContainer -- Constructor +func NewServerAPIContainer() (p *ServerAPIContainer) { + p = new(ServerAPIContainer) + p.Servers = make([]*ServerAPI, 0) + return p +} diff --git a/rvpn/connection/connection.go b/rvpn/connection/connection.go index 67fca8c..b65784a 100755 --- a/rvpn/connection/connection.go +++ b/rvpn/connection/connection.go @@ -14,13 +14,17 @@ var upgrader = websocket.Upgrader{ // Connection track websocket and faciliates in and out data type Connection struct { + // The main connection table (should be just one of these created at startup) connectionTable *Table + //used to track traffic for a domain. Not use for lookup or validation only for tracking + DomainTrack map[string]*DomainTrack + // The websocket connection. conn *websocket.Conn // Buffered channel of outbound messages. - send chan []byte + send chan *SendTrack // Address of the Remote End Point source string @@ -49,10 +53,28 @@ func NewConnection(connectionTable *Table, conn *websocket.Conn, remoteAddress s p.source = remoteAddress p.bytesIn = 0 p.bytesOut = 0 - p.send = make(chan []byte, 256) + p.send = make(chan *SendTrack) p.commCh = make(chan bool) p.connectTime = time.Now() p.initialDomains = initialDomains + p.DomainTrack = make(map[string]*DomainTrack) + + for _, domain := range initialDomains { + p.AddTrackedDomain(string(domain.(string))) + } + return +} + +//AddTrackedDomain -- Add a tracked domain +func (c *Connection) AddTrackedDomain(domain string) { + p := new(DomainTrack) + p.DomainName = domain + c.DomainTrack[domain] = p +} + +//InitialDomains -- Property +func (c *Connection) InitialDomains() (i []interface{}) { + i = c.initialDomains return } @@ -75,7 +97,7 @@ func (c *Connection) BytesOut() (b int64) { } //SendCh -- property to sending channel -func (c *Connection) SendCh() chan []byte { +func (c *Connection) SendCh() chan *SendTrack { return c.send } @@ -132,13 +154,25 @@ func (c *Connection) Writer() { if err != nil { return } - w.Write(message) + w.Write(message.data) if err := w.Close(); err != nil { return } - c.addOut(int64(len(message))) + messageLen := int64(len(message.data)) + + c.addOut(messageLen) + + //Support for tracking outbound traffic based on domain. + if domainTrack, ok := c.DomainTrack[message.domain]; ok { + //if ok then add to structure, else warn there is something wrong + domainTrack.AddOut(messageLen) + loginfo.Println("adding ", messageLen, " to ", message.domain) + } else { + logdebug.Println("attempting to add bytes to ", message.domain, "it does not exist") + logdebug.Println(c.DomainTrack) + } loginfo.Println(c) } } diff --git a/rvpn/connection/domain_track.go b/rvpn/connection/domain_track.go new file mode 100644 index 0000000..e2282a7 --- /dev/null +++ b/rvpn/connection/domain_track.go @@ -0,0 +1,39 @@ +package connection + +//DomainTrack -- Tracking specifics for domains +type DomainTrack struct { + DomainName string + bytesIn int64 + bytesOut int64 +} + +//NewDomainTrack -- Constructor +func NewDomainTrack(domainName string) (p *DomainTrack) { + p = new(DomainTrack) + p.DomainName = domainName + p.bytesIn = 0 + p.bytesOut = 0 + return +} + +//BytesIn -- Property +func (c *DomainTrack) BytesIn() (b int64) { + b = c.bytesIn + return +} + +//BytesOut -- Property +func (c *DomainTrack) BytesOut() (b int64) { + b = c.bytesOut + return +} + +//AddIn - Porperty +func (c *DomainTrack) AddIn(num int64) { + c.bytesIn = c.bytesIn + num +} + +//AddOut -- Property +func (c *DomainTrack) AddOut(num int64) { + c.bytesOut = c.bytesOut + num +} diff --git a/rvpn/connection/send_track.go b/rvpn/connection/send_track.go new file mode 100644 index 0000000..f7430b2 --- /dev/null +++ b/rvpn/connection/send_track.go @@ -0,0 +1,16 @@ +package connection + +//SendTrack -- Used as a channel communication to id domain asssociated to domain for outbound WSS +type SendTrack struct { + data []byte + domain string +} + +//NewSendTrack -- Constructor +func NewSendTrack(data []byte, domain string) (p *SendTrack) { + p = new(SendTrack) + p.data = data + p.domain = domain + return + +} diff --git a/rvpn/external/listener_webrequest.go b/rvpn/external/listener_webrequest.go index abe86ac..251d3d6 100644 --- a/rvpn/external/listener_webrequest.go +++ b/rvpn/external/listener_webrequest.go @@ -54,7 +54,8 @@ func LaunchWebRequestExternalListener(serverBinding *string, connectionTable *co p.Data.AppendBytes(dump) buf := p.PackV1() - conn.SendCh() <- buf.Bytes() + sendTrack := connection.NewSendTrack(buf.Bytes(), hostname) + conn.SendCh() <- sendTrack } } })