Several Considerations for Load Balancing, Collection of Bulk ServerStatus
- added a number of global status collections - this requires wedging into things.. - removing direct address to come functions putting them though serverStatus
This commit is contained in:
parent
057ec00f82
commit
ba67cebb29
|
@ -1,4 +1,5 @@
|
|||
rvpn:
|
||||
serverName: rvpn1
|
||||
wssdomain: localhost.daplie.me
|
||||
admindomain: rvpn.daplie.invalid
|
||||
genericlistener: 9999
|
||||
|
@ -14,6 +15,6 @@ rvpn:
|
|||
test3.daplie.me:
|
||||
secret: abc123
|
||||
loadbalancing:
|
||||
defaultmethod: 'round-robin'
|
||||
defaultmethod: round-robin
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
</div>
|
||||
<nav class="collapse navbar-collapse" id="bs-navbar">
|
||||
<ul class="nav navbar-nav">
|
||||
<li> <a href="/admin/status">Status</a> </li>
|
||||
<li> <a href="/admin/servers">Servers</a> </li>
|
||||
<li> <a href="/admin/#domains">Domains</a> </li>
|
||||
<li> <a href="/admin/#connections">Connections</a> </li>
|
||||
|
|
|
@ -4,15 +4,23 @@ var app = angular.module("rvpnApp", ["ngRoute", "angular-duration-format"]);
|
|||
|
||||
app.config(function($routeProvider, $locationProvider) {
|
||||
$routeProvider
|
||||
|
||||
.when("/admin/status/", {
|
||||
templateUrl : "admin/partials/status.html"
|
||||
})
|
||||
|
||||
.when("/admin/index.html", {
|
||||
templateUrl : "admin/partials/servers.html"
|
||||
})
|
||||
|
||||
.when("/admin/servers/", {
|
||||
templateUrl : "admin/partials/servers.html"
|
||||
})
|
||||
|
||||
.when("/admin/#domains", {
|
||||
templateUrl : "green.htm"
|
||||
})
|
||||
|
||||
.when("/blue", {
|
||||
templateUrl : "blue.htm"
|
||||
});
|
||||
|
@ -81,7 +89,7 @@ app.controller('serverController', function ($scope, $http) {
|
|||
}
|
||||
|
||||
$scope.triggerDetail = function(id) {
|
||||
console.log("triggerDetail ", id, $scope.servers_trigger_details[id])
|
||||
//console.log("triggerDetail ", id, $scope.servers_trigger_details[id])
|
||||
if ($scope.servers_trigger_details[id] == true) {
|
||||
$scope.servers_trigger_details[id] = false;
|
||||
} else {
|
||||
|
@ -90,7 +98,7 @@ app.controller('serverController', function ($scope, $http) {
|
|||
};
|
||||
|
||||
$scope.checkDetail = function(id) {
|
||||
console.log("checkDetail ", id, $scope.servers_trigger_details[id])
|
||||
//console.log("checkDetail ", id, $scope.servers_trigger_details[id])
|
||||
if ($scope.servers_trigger_details[id] == true) {
|
||||
return false;
|
||||
} else {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
<th width="10%">Name</th>
|
||||
<th width="10%">Address</th>
|
||||
<th width="10%">Xfer (in/out)</th>
|
||||
<th width="10%">Req/Resp</th>
|
||||
<th width="10%">Time</th>
|
||||
<th width="10%">Idle</th>
|
||||
<th width="1%"><center><span class="glyphicon glyphicon-option-vertical" aria-hidden="true"></span></center></th>
|
||||
|
@ -46,16 +47,34 @@
|
|||
<td>
|
||||
{{ s.bytes_in | bytes }}/{{ s.bytes_out | bytes }}
|
||||
<div ng-hide="checkDetail(s.server_id)">
|
||||
domains({{ s.domains.length}})
|
||||
 
|
||||
<div ng-repeat="d in s.domains | orderBy:'domain_name'">
|
||||
   {{ d.bytes_in | bytes }}/{{ d.bytes_out | bytes }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ s.requests }}/{{ s.responses }}
|
||||
<div ng-hide="checkDetail(s.server_id)">
|
||||
 
|
||||
<div ng-repeat="d in s.domains | orderBy:'domain_name'">
|
||||
   {{ d.requests }}/{{ d.responses }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>{{ s.duration | hfcduration }}</td>
|
||||
<td>{{ s.idle | hfcduration }}</td>
|
||||
<td>
|
||||
<span class="glyphicon glyphicon-zoom-in" title="Detail" aria-hidden="false" ng-click="triggerDetail(s.server_id)"></span>
|
||||
<div ng-hide="checkDetail(s.server_id)">
|
||||
 
|
||||
<div ng-repeat="d in s.domains | orderBy:'domain_name'">
|
||||
<span class="glyphicon glyphicon-zoom-in" title="Detail" aria-hidden="false" ng-click="triggerDetail(s.server_id+d.domain_name)"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<div class="panel panel-default" data-ng-controller="serverController">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
Status
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<form class="form-inline pull-right">
|
||||
<div class="form-group">
|
||||
<label for="search">Search:</label>
|
||||
<input type="text" class="form-control" id="search" data-ng-model="servers_search">
|
||||
</div>
|
||||
<button type="button" title="Refresh" class="btn btn-default" aria-label="Refresh">
|
||||
<span class="glyphicon glyphicon-refresh" title="Refresh" aria-hidden="false" ng-click="updateView()"></span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
24
main.go
24
main.go
|
@ -33,6 +33,7 @@ var (
|
|||
dwell int
|
||||
cancelcheck int
|
||||
lbDefaultMethod string
|
||||
serverName string
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -48,7 +49,7 @@ func main() {
|
|||
viper.AddConfigPath("./")
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Fatal error config file: %s \n", err))
|
||||
panic(fmt.Errorf("fatal error config file: %s", err))
|
||||
}
|
||||
|
||||
flag.IntVar(&argDeadTime, "dead-time-counter", 5, "deadtime counter in seconds")
|
||||
|
@ -61,6 +62,7 @@ func main() {
|
|||
dwell = deadtime.(map[string]interface{})["dwell"].(int)
|
||||
cancelcheck = deadtime.(map[string]interface{})["cancelcheck"].(int)
|
||||
lbDefaultMethod = viper.Get("rvpn.loadbalancing.defaultmethod").(string)
|
||||
serverName = viper.Get("rvpn.serverName").(string)
|
||||
|
||||
loginfo.Println("startup")
|
||||
|
||||
|
@ -78,6 +80,14 @@ func main() {
|
|||
ctx, cancelContext := context.WithCancel(context.Background())
|
||||
defer cancelContext()
|
||||
|
||||
serverStatus := genericlistener.NewStatus(ctx)
|
||||
serverStatus.AdminDomain = adminHostName
|
||||
serverStatus.WssDomain = wssHostName
|
||||
serverStatus.Name = serverName
|
||||
serverStatus.StartTime = time.Now()
|
||||
serverStatus.DeadTime = genericlistener.NewStatusDeadTime(dwell, idle, cancelcheck)
|
||||
serverStatus.LoadbalanceDefaultMethod = lbDefaultMethod
|
||||
|
||||
// Setup for GenericListenServe.
|
||||
// - establish context for the generic listener
|
||||
// - startup listener
|
||||
|
@ -88,17 +98,17 @@ func main() {
|
|||
// - match protocol
|
||||
|
||||
connectionTracking := genericlistener.NewTracking()
|
||||
serverStatus.ConnectionTracking = connectionTracking
|
||||
go connectionTracking.Run(ctx)
|
||||
|
||||
connectionTable = genericlistener.NewTable(dwell, idle)
|
||||
serverStatus.ConnectionTable = connectionTable
|
||||
go connectionTable.Run(ctx)
|
||||
|
||||
genericListeners := genericlistener.NewGenerListeners(ctx, connectionTable, connectionTracking, secretKey, certbundle, wssHostName,
|
||||
adminHostName, cancelcheck, lbDefaultMethod)
|
||||
genericListeners := genericlistener.NewGenerListeners(ctx, secretKey, certbundle, serverStatus)
|
||||
serverStatus.GenericListeners = genericListeners
|
||||
|
||||
genericListeners.Run(ctx, argGenericBinding)
|
||||
go genericListeners.Run(ctx, argGenericBinding)
|
||||
|
||||
//Run for 10 minutes and then shutdown cleanly
|
||||
time.Sleep(6000 * time.Second)
|
||||
cancelContext()
|
||||
select {}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ type DomainsAPI struct {
|
|||
ServerID int64 `json:"server_id"`
|
||||
BytesIn int64 `json:"bytes_in"`
|
||||
BytesOut int64 `json:"bytes_out"`
|
||||
Requests int64 `json:"requests"`
|
||||
Responses int64 `json:"responses"`
|
||||
}
|
||||
|
||||
//NewDomainsAPI - Constructor
|
||||
|
@ -15,6 +17,8 @@ func NewDomainsAPI(c *Connection, d *DomainTrack) (s *DomainsAPI) {
|
|||
s.ServerID = c.ConnectionID()
|
||||
s.BytesIn = d.BytesIn()
|
||||
s.BytesOut = d.BytesOut()
|
||||
s.Requests = d.requests
|
||||
s.Responses = d.responses
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -37,16 +41,20 @@ type DomainAPI struct {
|
|||
ServerID int64 `json:"server_id"`
|
||||
BytesIn int64 `json:"bytes_in"`
|
||||
BytesOut int64 `json:"bytes_out"`
|
||||
Requests int64 `json:"requests"`
|
||||
Responses int64 `json:"responses"`
|
||||
Source string `json:"source_addr"`
|
||||
}
|
||||
|
||||
//NewDomainsAPI - Constructor
|
||||
//NewDomainAPI - Constructor
|
||||
func NewDomainAPI(c *Connection, d *DomainTrack) (s *DomainAPI) {
|
||||
s = new(DomainAPI)
|
||||
s.DomainName = d.DomainName
|
||||
s.ServerID = c.ConnectionID()
|
||||
s.BytesIn = d.BytesIn()
|
||||
s.BytesOut = d.BytesOut()
|
||||
s.Requests = d.requests
|
||||
s.Responses = d.responses
|
||||
s.Source = c.Source()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ type ServersAPI struct {
|
|||
Idle float64 `json:"idle"`
|
||||
BytesIn int64 `json:"bytes_in"`
|
||||
BytesOut int64 `json:"bytes_out"`
|
||||
Requests int64 `json:"requests"`
|
||||
Responses int64 `json:"responses"`
|
||||
Source string `json:"source_address"`
|
||||
}
|
||||
|
||||
|
@ -27,6 +29,8 @@ func NewServersAPI(c *Connection) (s *ServersAPI) {
|
|||
s.Idle = time.Since(c.LastUpdate()).Seconds()
|
||||
s.BytesIn = c.BytesIn()
|
||||
s.BytesOut = c.BytesOut()
|
||||
s.Requests = c.requests
|
||||
s.Responses = c.responses
|
||||
s.Source = c.Source()
|
||||
|
||||
for d := range c.DomainTrack {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package genericlistener
|
||||
|
||||
import "time"
|
||||
|
||||
//StatusAPI -- Structure to support the server API
|
||||
type StatusAPI struct {
|
||||
Name string `json:"name"`
|
||||
Uptime float64 `json:"uptime"`
|
||||
WssDomain string `json:"wss_domain"`
|
||||
AdminDomain string `json:"admin_domain"`
|
||||
LoadbalanceDefaultMethod string `json:"loadbalance_default_method"`
|
||||
DeadTime *StatusDeadTimeAPI `json:"dead_time"`
|
||||
AdminStats *TrafficAPI `json:"admin_traffic"`
|
||||
TrafficStats *TrafficAPI `json:"traffic"`
|
||||
ExtConnections *ConnectionStats
|
||||
WSSConnections *ConnectionStats
|
||||
}
|
||||
|
||||
//NewStatusAPI - Constructor
|
||||
func NewStatusAPI(c *Status) (s *StatusAPI) {
|
||||
s = new(StatusAPI)
|
||||
s.Name = c.Name
|
||||
s.Uptime = time.Since(c.StartTime).Seconds()
|
||||
s.WssDomain = c.WssDomain
|
||||
s.AdminDomain = c.AdminDomain
|
||||
s.LoadbalanceDefaultMethod = c.LoadbalanceDefaultMethod
|
||||
s.DeadTime = NewStatusDeadTimeAPI(c.DeadTime.dwell, c.DeadTime.idle, c.DeadTime.cancelcheck)
|
||||
s.AdminStats = NewTrafficAPI(c.AdminStats.Requests, c.AdminStats.Responses, c.AdminStats.BytesIn, c.AdminStats.BytesOut)
|
||||
s.TrafficStats = NewTrafficAPI(c.TrafficStats.Requests, c.TrafficStats.Responses, c.TrafficStats.BytesIn, c.TrafficStats.BytesOut)
|
||||
|
||||
return
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package genericlistener
|
||||
|
||||
//StatusDeadTimeAPI -- structure for deadtime configuration
|
||||
type StatusDeadTimeAPI struct {
|
||||
Dwell int `json:"dwell"`
|
||||
Idle int `json:"idle"`
|
||||
Cancelcheck int `json:"cancel_check"`
|
||||
}
|
||||
|
||||
//NewStatusDeadTimeAPI -- constructor
|
||||
func NewStatusDeadTimeAPI(dwell int, idle int, cancelcheck int) (p *StatusDeadTimeAPI) {
|
||||
p = new(StatusDeadTimeAPI)
|
||||
p.Dwell = dwell
|
||||
p.Idle = idle
|
||||
p.Cancelcheck = cancelcheck
|
||||
return
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package genericlistener
|
||||
|
||||
//TrafficStats --
|
||||
type TrafficAPI struct {
|
||||
Requests int64
|
||||
Responses int64
|
||||
BytesIn int64
|
||||
BytesOut int64
|
||||
}
|
||||
|
||||
//NewTrafficStats -- Consttuctor
|
||||
func NewTrafficAPI(requests int64, responses int64, bytes_in int64, bytes_out int64) (p *TrafficAPI) {
|
||||
p = new(TrafficAPI)
|
||||
p.Requests = requests
|
||||
p.Responses = responses
|
||||
p.BytesIn = bytes_in
|
||||
p.BytesOut = bytes_out
|
||||
|
||||
return
|
||||
}
|
|
@ -16,12 +16,16 @@ const (
|
|||
)
|
||||
|
||||
var connectionTable *Table
|
||||
var serverStatusAPI *Status
|
||||
|
||||
//handleAdminClient -
|
||||
// - expecting an existing oneConnListener with a qualified wss client connected.
|
||||
// - auth will happen again since we were just peeking at the token.
|
||||
func handleAdminClient(ctx context.Context, oneConn *oneConnListener) {
|
||||
connectionTable = ctx.Value(ctxConnectionTable).(*Table)
|
||||
serverStatus := ctx.Value(ctxServerStatus).(*Status)
|
||||
|
||||
connectionTable = serverStatus.ConnectionTable
|
||||
serverStatusAPI = serverStatus
|
||||
router := mux.NewRouter().StrictSlash(true)
|
||||
|
||||
router.PathPrefix("/admin/").Handler(http.StripPrefix("/admin/", http.FileServer(http.Dir("html/admin"))))
|
||||
|
@ -46,6 +50,7 @@ func handleAdminClient(ctx context.Context, oneConn *oneConnListener) {
|
|||
router.HandleFunc(endPointPrefix+"servers", getServersEndpoint).Methods("GET")
|
||||
router.HandleFunc(endPointPrefix+"server/", getServerEndpoint).Methods("GET")
|
||||
router.HandleFunc(endPointPrefix+"server/{server-id}", getServerEndpoint).Methods("GET")
|
||||
router.HandleFunc(endPointPrefix+"status/", getStatusEndpoint).Methods("GET")
|
||||
|
||||
s := &http.Server{
|
||||
Addr: ":80",
|
||||
|
@ -64,6 +69,20 @@ func handleAdminClient(ctx context.Context, oneConn *oneConnListener) {
|
|||
}
|
||||
}
|
||||
|
||||
func getStatusEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
pc, _, _, _ := runtime.Caller(0)
|
||||
loginfo.Println(runtime.FuncForPC(pc).Name())
|
||||
|
||||
statusContainer := NewStatusAPI(serverStatusAPI)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
|
||||
env := envelope.NewEnvelope("domains/GET")
|
||||
env.Result = statusContainer
|
||||
env.GenerateWriter(w)
|
||||
|
||||
}
|
||||
|
||||
func getDomainsEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
pc, _, _, _ := runtime.Caller(0)
|
||||
loginfo.Println(runtime.FuncForPC(pc).Name())
|
||||
|
|
|
@ -50,6 +50,12 @@ type Connection struct {
|
|||
// bytes out
|
||||
bytesOut int64
|
||||
|
||||
// requests
|
||||
requests int64
|
||||
|
||||
// response
|
||||
responses int64
|
||||
|
||||
// Connect Time
|
||||
connectTime time.Time
|
||||
|
||||
|
@ -79,6 +85,8 @@ func NewConnection(connectionTable *Table, conn *websocket.Conn, remoteAddress s
|
|||
p.source = remoteAddress
|
||||
p.bytesIn = 0
|
||||
p.bytesOut = 0
|
||||
p.requests = 0
|
||||
p.responses = 0
|
||||
p.send = make(chan *SendTrack)
|
||||
p.connectTime = time.Now()
|
||||
p.initialDomains = initialDomains
|
||||
|
@ -143,6 +151,14 @@ func (c *Connection) addOut(num int64) {
|
|||
c.bytesOut = c.bytesOut + num
|
||||
}
|
||||
|
||||
func (c *Connection) addRequests() {
|
||||
c.requests = c.requests + 1
|
||||
}
|
||||
|
||||
func (c *Connection) addResponse() {
|
||||
c.responses = c.responses + 1
|
||||
}
|
||||
|
||||
//ConnectionTable -- property
|
||||
func (c *Connection) ConnectionTable() (table *Table) {
|
||||
table = c.connectionTable
|
||||
|
@ -251,12 +267,14 @@ func (c *Connection) Reader(ctx context.Context) {
|
|||
//Support for tracking outbound traffic based on domain.
|
||||
if domainTrack, ok := c.DomainTrack[track.domain]; ok {
|
||||
//if ok then add to structure, else warn there is something wrong
|
||||
domainTrack.AddIn(int64(len(message)))
|
||||
domainTrack.AddOut(int64(len(message)))
|
||||
domainTrack.AddResponses()
|
||||
}
|
||||
|
||||
track.conn.Write(p.Data.Data())
|
||||
|
||||
c.addIn(int64(len(message)))
|
||||
c.addResponse()
|
||||
loginfo.Println("end of read")
|
||||
}
|
||||
}
|
||||
|
@ -290,11 +308,13 @@ func (c *Connection) Writer() {
|
|||
messageLen := int64(len(message.data))
|
||||
|
||||
c.addOut(messageLen)
|
||||
c.addRequests()
|
||||
|
||||
//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)
|
||||
domainTrack.AddIn(messageLen)
|
||||
domainTrack.AddRequests()
|
||||
loginfo.Println("adding ", messageLen, " to ", message.domain)
|
||||
} else {
|
||||
logdebug.Println("attempting to add bytes to ", message.domain, "it does not exist")
|
||||
|
|
|
@ -5,6 +5,8 @@ type DomainTrack struct {
|
|||
DomainName string
|
||||
bytesIn int64
|
||||
bytesOut int64
|
||||
requests int64
|
||||
responses int64
|
||||
}
|
||||
|
||||
//NewDomainTrack -- Constructor
|
||||
|
@ -13,6 +15,8 @@ func NewDomainTrack(domainName string) (p *DomainTrack) {
|
|||
p.DomainName = domainName
|
||||
p.bytesIn = 0
|
||||
p.bytesOut = 0
|
||||
p.requests = 0
|
||||
p.responses = 0
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -28,7 +32,7 @@ func (c *DomainTrack) BytesOut() (b int64) {
|
|||
return
|
||||
}
|
||||
|
||||
//AddIn - Porperty
|
||||
//AddIn - Property
|
||||
func (c *DomainTrack) AddIn(num int64) {
|
||||
c.bytesIn = c.bytesIn + num
|
||||
}
|
||||
|
@ -37,3 +41,13 @@ func (c *DomainTrack) AddIn(num int64) {
|
|||
func (c *DomainTrack) AddOut(num int64) {
|
||||
c.bytesOut = c.bytesOut + num
|
||||
}
|
||||
|
||||
//AddRequests - Property
|
||||
func (c *DomainTrack) AddRequests() {
|
||||
c.requests = c.requests + 1
|
||||
}
|
||||
|
||||
//AddResponses - Property
|
||||
func (c *DomainTrack) AddResponses() {
|
||||
c.responses = c.responses + 1
|
||||
}
|
||||
|
|
|
@ -26,8 +26,11 @@ type contextKey string
|
|||
|
||||
//CtxConnectionTrack
|
||||
const (
|
||||
ctxSecretKey contextKey = "secretKey"
|
||||
ctxConnectionTable contextKey = "connectionTable"
|
||||
ctxSecretKey contextKey = "secretKey"
|
||||
ctxServerStatus contextKey = "serverstatus"
|
||||
|
||||
//ctxConnectionTable contextKey = "connectionTable"
|
||||
|
||||
ctxConfig contextKey = "config"
|
||||
ctxListenerRegistration contextKey = "listenerRegistration"
|
||||
ctxConnectionTrack contextKey = "connectionTrack"
|
||||
|
@ -271,16 +274,16 @@ func handleStream(ctx context.Context, wConn *WedgeConn) {
|
|||
//handleExternalHTTPRequest -
|
||||
// - get a wConn and start processing requests
|
||||
func handleExternalHTTPRequest(ctx context.Context, extConn *WedgeConn, hostname string, service string) {
|
||||
connectionTracking := ctx.Value(ctxConnectionTrack).(*Tracking)
|
||||
//connectionTracking := ctx.Value(ctxConnectionTrack).(*Tracking)
|
||||
serverStatus := ctx.Value(ctxServerStatus).(*Status)
|
||||
|
||||
defer func() {
|
||||
connectionTracking.unregister <- extConn
|
||||
serverStatus.ExtConnectionUnregister(extConn)
|
||||
extConn.Close()
|
||||
}()
|
||||
|
||||
connectionTable := ctx.Value(ctxConnectionTable).(*Table)
|
||||
//find the connection by domain name
|
||||
conn, ok := connectionTable.ConnByDomain(hostname)
|
||||
conn, ok := serverStatus.ConnectionTable.ConnByDomain(hostname)
|
||||
if !ok {
|
||||
//matching connection can not be found based on ConnByDomain
|
||||
loginfo.Println("unable to match ", hostname, " to an existing connection")
|
||||
|
@ -289,7 +292,7 @@ func handleExternalHTTPRequest(ctx context.Context, extConn *WedgeConn, hostname
|
|||
}
|
||||
|
||||
track := NewTrack(extConn, hostname)
|
||||
connectionTracking.register <- track
|
||||
serverStatus.ExtConnectionRegister(track)
|
||||
|
||||
loginfo.Println("Domain Accepted", hostname, extConn.RemoteAddr().String())
|
||||
|
||||
|
@ -322,10 +325,11 @@ func handleExternalHTTPRequest(ctx context.Context, extConn *WedgeConn, hostname
|
|||
p.Data.AppendBytes(buffer[0:cnt])
|
||||
buf := p.PackV1()
|
||||
|
||||
loginfo.Println(hex.Dump(buf.Bytes()))
|
||||
//loginfo.Println(hex.Dump(buf.Bytes()))
|
||||
|
||||
//Bundle up the send request and dispatch
|
||||
sendTrack := NewSendTrack(buf.Bytes(), hostname)
|
||||
conn.SendCh() <- sendTrack
|
||||
serverStatus.SendExtRequest(conn, sendTrack)
|
||||
|
||||
_, err = extConn.Discard(cnt)
|
||||
if err != nil {
|
||||
|
@ -341,7 +345,9 @@ func handleExternalHTTPRequest(ctx context.Context, extConn *WedgeConn, hostname
|
|||
// - auth will happen again since we were just peeking at the token.
|
||||
func handleWssClient(ctx context.Context, oneConn *oneConnListener) {
|
||||
secretKey := ctx.Value(ctxSecretKey).(string)
|
||||
connectionTable := ctx.Value(ctxConnectionTable).(*Table)
|
||||
serverStatus := ctx.Value(ctxServerStatus).(*Status)
|
||||
|
||||
//connectionTable := ctx.Value(ctxConnectionTable).(*Table)
|
||||
|
||||
router := mux.NewRouter().StrictSlash(true)
|
||||
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -380,9 +386,10 @@ func handleWssClient(ctx context.Context, oneConn *oneConnListener) {
|
|||
|
||||
//newConnection := connection.NewConnection(connectionTable, conn, r.RemoteAddr, domains)
|
||||
|
||||
connectionTrack := ctx.Value(ctxConnectionTrack).(*Tracking)
|
||||
newRegistration := NewRegistration(conn, r.RemoteAddr, domains, connectionTrack)
|
||||
connectionTable.Register() <- newRegistration
|
||||
//connectionTrack := ctx.Value(ctxConnectionTrack).(*Tracking)
|
||||
newRegistration := NewRegistration(conn, r.RemoteAddr, domains, serverStatus.ConnectionTracking)
|
||||
serverStatus.WSSConnectionRegister(newRegistration)
|
||||
|
||||
ok = <-newRegistration.CommCh()
|
||||
if !ok {
|
||||
loginfo.Println("connection registration failed ", newRegistration)
|
||||
|
|
|
@ -57,23 +57,24 @@ type GenericListeners struct {
|
|||
adminHostName string
|
||||
cancelCheck int
|
||||
lbDefaultMethod string
|
||||
serverStatus *Status
|
||||
}
|
||||
|
||||
//NewGenerListeners --
|
||||
func NewGenerListeners(ctx context.Context, connectionTable *Table, connectionTrack *Tracking, secretKey string, certbundle tls.Certificate,
|
||||
wssHostName string, adminHostName string, cancelCheck int, lbDefaultMethod string) (p *GenericListeners) {
|
||||
func NewGenerListeners(ctx context.Context, secretKey string, certbundle tls.Certificate, serverStatus *Status) (p *GenericListeners) {
|
||||
p = new(GenericListeners)
|
||||
p.listeners = make(map[*net.Listener]int)
|
||||
p.ctx = ctx
|
||||
p.connnectionTable = connectionTable
|
||||
p.connectionTracking = connectionTrack
|
||||
p.connnectionTable = serverStatus.ConnectionTable
|
||||
p.connectionTracking = serverStatus.ConnectionTracking
|
||||
p.secretKey = secretKey
|
||||
p.certbundle = certbundle
|
||||
p.register = make(chan *ListenerRegistration)
|
||||
p.wssHostName = wssHostName
|
||||
p.adminHostName = adminHostName
|
||||
p.cancelCheck = cancelCheck
|
||||
p.lbDefaultMethod = lbDefaultMethod
|
||||
p.wssHostName = serverStatus.WssDomain
|
||||
p.adminHostName = serverStatus.AdminDomain
|
||||
p.cancelCheck = serverStatus.DeadTime.cancelcheck
|
||||
p.lbDefaultMethod = serverStatus.LoadbalanceDefaultMethod
|
||||
p.serverStatus = serverStatus
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -86,7 +87,6 @@ func (gl *GenericListeners) Run(ctx context.Context, initialPort int) {
|
|||
config := &tls.Config{Certificates: []tls.Certificate{gl.certbundle}}
|
||||
|
||||
ctx = context.WithValue(ctx, ctxSecretKey, gl.secretKey)
|
||||
ctx = context.WithValue(ctx, ctxConnectionTable, gl.connnectionTable)
|
||||
|
||||
loginfo.Println(gl.connectionTracking)
|
||||
|
||||
|
@ -97,6 +97,7 @@ func (gl *GenericListeners) Run(ctx context.Context, initialPort int) {
|
|||
ctx = context.WithValue(ctx, ctxAdminHostName, gl.adminHostName)
|
||||
ctx = context.WithValue(ctx, ctxCancelCheck, gl.cancelCheck)
|
||||
ctx = context.WithValue(ctx, ctxLoadbalanceDefaultMethod, gl.lbDefaultMethod)
|
||||
ctx = context.WithValue(ctx, ctxServerStatus, gl.serverStatus)
|
||||
|
||||
go func(ctx context.Context) {
|
||||
for {
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package genericlistener
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
//Status --
|
||||
type Status struct {
|
||||
ctx context.Context
|
||||
Name string
|
||||
StartTime time.Time
|
||||
WssDomain string
|
||||
AdminDomain string
|
||||
DeadTime *StatusDeadTime
|
||||
ConnectionTracking *Tracking
|
||||
ConnectionTable *Table
|
||||
GenericListeners *GenericListeners
|
||||
LoadbalanceDefaultMethod string
|
||||
AdminStats *TrafficStats
|
||||
TrafficStats *TrafficStats
|
||||
ExtConnections *ConnectionStats
|
||||
WSSConnections *ConnectionStats
|
||||
}
|
||||
|
||||
//NewStatus --
|
||||
func NewStatus(ctx context.Context) (p *Status) {
|
||||
p = new(Status)
|
||||
p.ctx = ctx
|
||||
p.AdminStats = new(TrafficStats)
|
||||
p.TrafficStats = new(TrafficStats)
|
||||
p.ExtConnections = new(ConnectionStats)
|
||||
p.WSSConnections = new(ConnectionStats)
|
||||
return
|
||||
}
|
||||
|
||||
// South Facing Functions
|
||||
|
||||
//WSSConnectionRegister --
|
||||
func (p *Status) WSSConnectionRegister(newRegistration *Registration) {
|
||||
p.ConnectionTable.Register() <- newRegistration
|
||||
p.WSSConnections.IncConnections()
|
||||
}
|
||||
|
||||
//WSSConnectionUnregister --
|
||||
//unregisters a south facing connection
|
||||
//intercept and update global statistics
|
||||
func (p *Status) WSSConnectionUnregister() {
|
||||
|
||||
}
|
||||
|
||||
// External Facing Functions
|
||||
|
||||
//ExtConnectionRegister --
|
||||
//registers an ext facing connection
|
||||
//intercept and update global statistics
|
||||
func (p *Status) ExtConnectionRegister(newTrack *Track) {
|
||||
p.ConnectionTracking.register <- newTrack
|
||||
p.ExtConnections.IncConnections()
|
||||
}
|
||||
|
||||
//ExtConnectionUnregister --
|
||||
//unregisters an ext facing connection
|
||||
//intercept and update global statistics
|
||||
func (p *Status) ExtConnectionUnregister(extConn *WedgeConn) {
|
||||
p.ConnectionTracking.unregister <- extConn
|
||||
p.ExtConnections.DecConnections()
|
||||
|
||||
}
|
||||
|
||||
//SendExtRequest --
|
||||
//sends a request to a south facing connection
|
||||
//intercept the send, update our global stats
|
||||
func (p *Status) SendExtRequest(conn *Connection, sendTrack *SendTrack) {
|
||||
p.TrafficStats.IncRequests()
|
||||
p.TrafficStats.AddBytesOut(int64(len(sendTrack.data)))
|
||||
conn.SendCh() <- sendTrack
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package genericlistener
|
||||
|
||||
//StatusDeadTime -- structure for deadtime configuration
|
||||
type StatusDeadTime struct {
|
||||
dwell int
|
||||
idle int
|
||||
cancelcheck int
|
||||
}
|
||||
|
||||
//NewStatusDeadTime -- constructor
|
||||
func NewStatusDeadTime(dwell int, idle int, cancelcheck int) (p *StatusDeadTime) {
|
||||
p = new(StatusDeadTime)
|
||||
p.dwell = dwell
|
||||
p.idle = idle
|
||||
p.cancelcheck = cancelcheck
|
||||
return
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package genericlistener
|
||||
|
||||
//ConnectionStats --
|
||||
type ConnectionStats struct {
|
||||
Connections int64
|
||||
}
|
||||
|
||||
//NewConnectionStats -- Consttuctor
|
||||
func NewConnectionStats() (p *ConnectionStats) {
|
||||
p = new(ConnectionStats)
|
||||
p.Connections = 0
|
||||
return
|
||||
}
|
||||
|
||||
//IncConnections --
|
||||
func (p *ConnectionStats) IncConnections() {
|
||||
p.Connections++
|
||||
}
|
||||
|
||||
//DecConnections --
|
||||
func (p *ConnectionStats) DecConnections() {
|
||||
p.Connections--
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package genericlistener
|
||||
|
||||
//TrafficStats --
|
||||
type TrafficStats struct {
|
||||
Requests int64
|
||||
Responses int64
|
||||
BytesIn int64
|
||||
BytesOut int64
|
||||
}
|
||||
|
||||
//NewTrafficStats -- Consttuctor
|
||||
func NewTrafficStats() (p *TrafficStats) {
|
||||
p = new(TrafficStats)
|
||||
p.Requests = 0
|
||||
p.Responses = 0
|
||||
p.BytesIn = 0
|
||||
p.BytesOut = 0
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//IncRequests --
|
||||
func (p *TrafficStats) IncRequests() {
|
||||
p.Requests++
|
||||
}
|
||||
|
||||
//IncResponses --
|
||||
func (p *TrafficStats) IncResponses() {
|
||||
p.Responses++
|
||||
}
|
||||
|
||||
//AddBytesIn --
|
||||
func (p *TrafficStats) AddBytesIn(count int64) {
|
||||
p.BytesIn = p.BytesIn + count
|
||||
}
|
||||
|
||||
//AddBytesOut --
|
||||
func (p *TrafficStats) AddBytesOut(count int64) {
|
||||
p.BytesOut = p.BytesOut + count
|
||||
}
|
Loading…
Reference in New Issue