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

View File

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

View File

@ -41,19 +41,19 @@ func NewTracking() (p *Tracking) {
//Run - //Run -
func (p *Tracking) Run(ctx context.Context) { func (p *Tracking) Run(ctx context.Context) {
log.Println("Tracking Running") log.Println("[track] Tracking Running")
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
log.Println("Cancel signal hit") log.Println("[track] Cancel signal hit")
return return
case connection := <-p.register: case connection := <-p.register:
p.mutex.Lock() p.mutex.Lock()
key := connection.conn.RemoteAddr().String() key := connection.conn.RemoteAddr().String()
log.Println("register fired", key) log.Println("[track] register fired", key)
p.connections[key] = connection p.connections[key] = connection
p.list() p.list()
p.mutex.Unlock() p.mutex.Unlock()
@ -61,7 +61,7 @@ func (p *Tracking) Run(ctx context.Context) {
case connection := <-p.unregister: case connection := <-p.unregister:
p.mutex.Lock() p.mutex.Lock()
key := connection.RemoteAddr().String() key := connection.RemoteAddr().String()
log.Println("unregister fired", key) log.Println("[track] unregister fired", key)
if _, ok := p.connections[key]; ok { if _, ok := p.connections[key]; ok {
delete(p.connections, key) delete(p.connections, key)
} }
@ -73,7 +73,7 @@ func (p *Tracking) Run(ctx context.Context) {
func (p *Tracking) list() { func (p *Tracking) list() {
for c := range p.connections { 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 // - execute the GenericLister
// - pass initial port, we'll announce that // - pass initial port, we'll announce that
func (mx *MPlexy) Run() error { 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 ctx := mx.ctx
@ -145,30 +145,30 @@ func (mx *MPlexy) Run() error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
loginfo.Println("Cancel signal hit") loginfo.Println("[mplexy] Cancel signal hit")
return nil return nil
case registration := <-mx.register: 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 // check to see if port is already running
for listener := range mx.listeners { for listener := range mx.listeners {
if mx.listeners[listener] == registration.port { 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.status = listenerExists
registration.commCh <- registration registration.commCh <- registration
} }
} }
loginfo.Println("listener starting up ", registration.port) loginfo.Println("[mplexy] listener starting up ", registration.port)
loginfo.Println("[track]", ctx.Value(ctxConnectionTrack).(*api.Tracking)) loginfo.Println("[mplexy]", ctx.Value(ctxConnectionTrack).(*api.Tracking))
go mx.multiListenAndServe(ctx, registration) go mx.multiListenAndServe(ctx, registration)
status := <-registration.commCh status := <-registration.commCh
if status.status == listenerAdded { if status.status == listenerAdded {
mx.listeners[status.listener] = status.port mx.listeners[status.listener] = status.port
} else if status.status == listenerFault { } 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)
} }
} }
} }