improve logging, bugfix client args parsing

This commit is contained in:
AJ ONeal 2020-05-01 02:18:47 -06:00
parent 7d6437f4c5
commit fac06a1d66
5 changed files with 119 additions and 76 deletions

View File

@ -40,70 +40,103 @@ type proxy struct {
port int
}
func addLocals(proxies []proxy, location string) []proxy {
func addLocals(proxies []proxy, location string) ([]proxy, error) {
parts := strings.Split(location, ":")
if len(parts) > 3 {
panic(fmt.Sprintf("provided invalid location %q", location))
if len(parts) > 3 || "" == parts[0] {
return nil, fmt.Errorf("provided invalid --locals %q", location)
}
// Format can be any of
// <hostname> or <port> or <proto>:<port> or <proto>:<hostname>:<port>
n := len(parts)
i := n - 1
last := parts[i]
port, err := strconv.Atoi(last)
if nil != err {
// The last item is the hostname,
// which means it should be the only item
if n > 1 {
return nil, fmt.Errorf("provided invalid --locals %q", location)
}
// accepting all defaults
// If all that was provided as a "local" is the domain name we assume that domain
// has HTTP and HTTPS handlers on the default ports.
if len(parts) == 1 {
proxies = append(proxies, proxy{"http", parts[0], 80})
proxies = append(proxies, proxy{"https", parts[0], 443})
return proxies
last = strings.ToLower(strings.Trim(last, "/"))
proxies = append(proxies, proxy{"http", last, 80})
proxies = append(proxies, proxy{"https", last, 443})
return proxies, nil
}
// Make everything lower case and trim any slashes in something like https://john.example.com
parts[0] = strings.ToLower(parts[0])
parts[1] = strings.ToLower(strings.Trim(parts[1], "/"))
if len(parts) == 2 {
if strings.Contains(parts[1], ".") {
if parts[0] == "http" {
parts = append(parts, "80")
} else if parts[0] == "https" {
parts = append(parts, "443")
} else {
panic(fmt.Sprintf("port must be specified for %q", location))
}
} else {
// https:3443 -> https:*:3443
parts = []string{parts[0], "*", parts[1]}
}
// the last item is the port, and it must be a valid port
if port <= 0 || port > 65535 {
return nil, fmt.Errorf("local port forward must be between 1 and 65535, not %d", port)
}
if port, err := strconv.Atoi(parts[2]); err != nil {
panic(fmt.Sprintf("port must be a valid number, not %q: %v", parts[2], err))
} else if port <= 0 || port > 65535 {
panic(fmt.Sprintf("%d is an invalid port for local services", port))
switch n {
case 1:
// <port>
proxies = append(proxies, proxy{"http", "*", port})
proxies = append(proxies, proxy{"https", "*", port})
case 2:
// <hostname>:<port>
// <scheme>:<port>
parts[0] = strings.ToLower(strings.Trim(parts[0], "/"))
if strings.Contains(parts[0], ".") {
hostname := parts[0]
proxies = append(proxies, proxy{"http", hostname, port})
proxies = append(proxies, proxy{"https", hostname, port})
} else {
proxies = append(proxies, proxy{parts[0], parts[1], port})
scheme := parts[0]
proxies = append(proxies, proxy{scheme, "*", port})
}
return proxies
case 3:
// <scheme>:<hostname>:<port>
scheme := strings.ToLower(strings.Trim(parts[0], "/"))
hostname := strings.ToLower(strings.Trim(parts[1], "/"))
proxies = append(proxies, proxy{scheme, hostname, port})
}
return proxies, nil
}
func addDomains(proxies []proxy, location string) []proxy {
func addDomains(proxies []proxy, location string) ([]proxy, error) {
parts := strings.Split(location, ":")
if len(parts) > 3 {
panic(fmt.Sprintf("provided invalid location %q", location))
} else if len(parts) == 2 {
panic("invalid argument for --domains, use format <domainname> or <scheme>:<domainname>:<local-port>")
if len(parts) > 3 || "" == parts[0] {
return nil, fmt.Errorf("provided invalid --domains %q", location)
}
// If the scheme and port weren't provided use the zero values
if len(parts) == 1 {
return append(proxies, proxy{"", parts[0], 0})
// Format is limited to
// <hostname> or <proto>:<hostname>:<port>
err := fmt.Errorf("invalid argument for --domains, use format <domainname> or <scheme>:<domainname>:<local-port>")
switch len(parts) {
case 1:
// TODO test that it's a valid pattern for a domain
hostname := parts[0]
if !strings.Contains(hostname, ".") {
return nil, err
}
proxies = append(proxies, proxy{"http", hostname, 80})
proxies = append(proxies, proxy{"https", hostname, 443})
case 2:
return nil, err
case 3:
scheme := parts[0]
hostname := parts[1]
if "" == scheme {
return nil, err
}
if !strings.Contains(hostname, ".") {
return nil, err
}
port, _ := strconv.Atoi(parts[2])
if port <= 0 || port > 65535 {
return nil, err
}
proxies = append(proxies, proxy{scheme, hostname, port})
}
if port, err := strconv.Atoi(parts[2]); err != nil {
panic(fmt.Sprintf("port must be a valid number, not %q: %v", parts[2], err))
} else if port <= 0 || port > 65535 {
panic(fmt.Sprintf("%d is an invalid port for local services", port))
} else {
proxies = append(proxies, proxy{parts[0], parts[1], port})
}
return proxies
return proxies, nil
}
func extractServicePorts(proxies []proxy) map[string]map[string]int {
@ -150,15 +183,25 @@ func extractServicePorts(proxies []proxy) map[string]map[string]int {
func main() {
flag.Parse()
var err error
proxies := make([]proxy, 0)
for _, option := range viper.GetStringSlice("locals") {
for _, location := range strings.Split(option, ",") {
proxies = addLocals(proxies, location)
//fmt.Println("locals", location)
proxies, err = addLocals(proxies, location)
if nil != err {
panic(err)
}
}
}
//fmt.Println("proxies:")
//fmt.Printf("%+v\n\n", proxies)
for _, option := range viper.GetStringSlice("domains") {
for _, location := range strings.Split(option, ",") {
proxies = addDomains(proxies, location)
proxies, err = addDomains(proxies, location)
if nil != err {
panic(err)
}
}
}

View File

@ -320,7 +320,7 @@ func (c *Connection) Writer() {
log.Println("adding ", messageLen, " to ", message.domain)
} else {
log.Println("attempting to add bytes to ", message.domain, "it does not exist")
log.Println(c.DomainTrack)
log.Println("dt", c.DomainTrack)
}
log.Println(c)
}

View File

@ -50,10 +50,10 @@ func (c *Table) Connections() map[*Connection][]string {
//back to the WSS connections
func (c *Table) ConnByDomain(domain string) (*Connection, bool) {
for dn := range c.Domains {
log.Println(dn, domain)
log.Println("[table]", dn, domain)
}
if domainsLB, ok := c.Domains[domain]; ok {
log.Println("found")
log.Println("[table] found")
conn := domainsLB.NextMember()
return conn, ok
}
@ -64,14 +64,14 @@ func (c *Table) ConnByDomain(domain string) (*Connection, bool) {
func (c *Table) reaper(delay int, idle int) {
_ = "breakpoint"
for {
log.Println("Reaper waiting for ", delay, " seconds")
log.Println("[table] Reaper waiting for ", delay, " seconds")
time.Sleep(time.Duration(delay) * time.Second)
log.Println("Running scanning ", len(c.connections))
log.Println("[table] Running scanning ", len(c.connections))
for d := range c.connections {
if !d.State() {
if time.Since(d.lastUpdate).Seconds() > float64(idle) {
log.Println("reaper removing ", d.lastUpdate, time.Since(d.lastUpdate).Seconds())
log.Println("[table] reaper removing ", d.lastUpdate, time.Since(d.lastUpdate).Seconds())
delete(c.connections, d)
}
}
@ -92,7 +92,7 @@ func (c *Table) GetConnection(serverID int64) (*Connection, error) {
//Run -- Execute
func (c *Table) Run(ctx context.Context) {
log.Println("ConnectionTable starting")
log.Println("[table] ConnectionTable starting")
go c.reaper(c.dwell, c.idle)
@ -100,11 +100,11 @@ func (c *Table) Run(ctx context.Context) {
select {
case <-ctx.Done():
log.Println("Cancel signal hit")
log.Println("[table] Cancel signal hit")
return
case registration := <-c.register:
log.Println("register fired")
log.Println("[table] register fired")
connection := NewConnection(c, registration.conn, registration.source, registration.initialDomains,
registration.connectionTrack, registration.serverName)
@ -116,7 +116,7 @@ func (c *Table) Run(ctx context.Context) {
// add to the domains regirstation
newDomain := domain
log.Println("adding domain ", newDomain, " to connection ", connection.conn.RemoteAddr().String())
log.Println("[table] adding domain ", newDomain, " to connection ", connection.conn.RemoteAddr().String())
//check to see if domain is already present.
if _, ok := c.Domains[newDomain]; ok {
@ -137,14 +137,14 @@ func (c *Table) Run(ctx context.Context) {
go connection.Reader(ctx)
case connection := <-c.unregister:
log.Println("closing connection ", connection.conn.RemoteAddr().String())
log.Println("[table] closing connection ", connection.conn.RemoteAddr().String())
//does connection exist in the connection table -- should never be an issue
if _, ok := c.connections[connection]; ok {
//iterate over the connections for the domain
for _, domain := range c.connections[connection] {
log.Println("remove domain", domain)
log.Println("[table] remove domain", domain)
//removing domain, make sure it is present (should never be a problem)
if _, ok := c.Domains[domain]; ok {
@ -166,7 +166,7 @@ func (c *Table) Run(ctx context.Context) {
}
case domainMapping := <-c.domainAnnounce:
log.Println("domainMapping fired ", domainMapping)
log.Println("[table] 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 {

View File

@ -41,19 +41,19 @@ func NewTracking() (p *Tracking) {
//Run -
func (p *Tracking) Run(ctx context.Context) {
log.Println("Tracking Running")
log.Println("[track] Tracking Running")
for {
select {
case <-ctx.Done():
log.Println("Cancel signal hit")
log.Println("[track] Cancel signal hit")
return
case connection := <-p.register:
p.mutex.Lock()
key := connection.conn.RemoteAddr().String()
log.Println("register fired", key)
log.Println("[track] register fired", key)
p.connections[key] = connection
p.list()
p.mutex.Unlock()
@ -61,7 +61,7 @@ func (p *Tracking) Run(ctx context.Context) {
case connection := <-p.unregister:
p.mutex.Lock()
key := connection.RemoteAddr().String()
log.Println("unregister fired", key)
log.Println("[track] unregister fired", key)
if _, ok := p.connections[key]; ok {
delete(p.connections, key)
}
@ -73,7 +73,7 @@ func (p *Tracking) Run(ctx context.Context) {
func (p *Tracking) list() {
for c := range p.connections {
log.Println(c)
log.Println("[track] list", c)
}
}

View File

@ -124,9 +124,9 @@ func (mx *MPlexy) AdminDomain() string {
// - execute the GenericLister
// - pass initial port, we'll announce that
func (mx *MPlexy) Run() error {
loginfo.Println("ConnectionTable starting")
loginfo.Println("[mplexy] ConnectionTable starting")
loginfo.Println(mx.connectionTracking)
loginfo.Println("[mplexy] ct ", mx.connectionTracking)
ctx := mx.ctx
@ -145,30 +145,30 @@ func (mx *MPlexy) Run() error {
select {
case <-ctx.Done():
loginfo.Println("Cancel signal hit")
loginfo.Println("[mplexy] Cancel signal hit")
return nil
case registration := <-mx.register:
loginfo.Println("register fired", registration.port)
loginfo.Println("[mplexy] register fired", registration.port)
// check to see if port is already running
for listener := range mx.listeners {
if mx.listeners[listener] == registration.port {
loginfo.Println("listener already running", registration.port)
loginfo.Println("[mplexy] listener already running", registration.port)
registration.status = listenerExists
registration.commCh <- registration
}
}
loginfo.Println("listener starting up ", registration.port)
loginfo.Println("[track]", ctx.Value(ctxConnectionTrack).(*api.Tracking))
loginfo.Println("[mplexy] listener starting up ", registration.port)
loginfo.Println("[mplexy]", ctx.Value(ctxConnectionTrack).(*api.Tracking))
go mx.multiListenAndServe(ctx, registration)
status := <-registration.commCh
if status.status == listenerAdded {
mx.listeners[status.listener] = status.port
} else if status.status == listenerFault {
loginfo.Println("Unable to create a new listerer", registration.port)
loginfo.Println("[mplexy] Unable to create a new listerer", registration.port)
}
}
}