updated to include domain stat traffic

- add support for domain_api container for JSON encoding
- separated server api containers out of the listener_admin
- added domain track to connection
- add extension to the send channel to identify domain associated to send bytes
- helper function for adding tracked domain
- implemented outbound byte counter for domain (inbound will come when we resolve the packer issues)
This commit is contained in:
Henry Camacho 2017-02-15 20:06:26 -06:00
parent 3dbdd694df
commit fc89682b9e
8 changed files with 174 additions and 43 deletions

View File

@ -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.

29
rvpn/admin/domain_api.go Normal file
View File

@ -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
// }

View File

@ -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")

46
rvpn/admin/server_api.go Normal file
View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}
}
})