func (p *ProxyListener) initAuthenticatedListeners() {
	locations, err := p.policyList.GetAuthenticatedPolicyAddresses()
	if err != nil {
		log.Criticalf("ProxyListener.initAuthenticatedListeners failure: %s", err)
		panic(err)
	}
	for location, policy := range locations {
		copyPolicy := policy
		handleNewConnection := func(conn net.Conn) error {
			log.Debugf("connection received %s:%s -> %s:%s\n", conn.RemoteAddr().Network(),
				conn.RemoteAddr().String(), conn.LocalAddr().Network(), conn.LocalAddr().String())
			s := NewAuthProxySession(conn, p.cfg.TorControlNet, p.cfg.TorControlAddress, p.onionDenyAddrs, p.watch, &copyPolicy)
			s.sessionWorker()
			return nil
		}
		log.Noticef("%s listener starting on %s:%s", policy.Name, location.Net, location.Address)
		p.authedServices = append(p.authedServices, service.NewMortalService(location.Net, location.Address, handleNewConnection))
		err = p.authedServices[len(p.authedServices)-1].Start()
		if err != nil {
			log.Criticalf("ProxyListener.initAuthenticatedListeners: roflcoptor failed to start service listeners: %s", err)
			return
		}
	}
}
InitAuthenticatedListeners runs each auth listener
in it's own goroutine.
package proxy
import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"net"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"github.com/op/go-logging"
	"github.com/subgraph/roflcoptor/common"
	"github.com/subgraph/roflcoptor/filter"
	"github.com/subgraph/roflcoptor/ozclient"
	"github.com/subgraph/roflcoptor/service"
	"github.com/yawning/bulb"
)
var log = logging.MustGetLogger("roflcoptor")
const (
	cmdProtocolInfo  = "PROTOCOLINFO"
	cmdAuthenticate  = "AUTHENTICATE"
	cmdAuthChallenge = "AUTHCHALLENGE"
	cmdQuit          = "QUIT"
	cmdGetInfo       = "GETINFO"
	cmdSignal        = "SIGNAL"
	responseOk = "250 OK\r\n"
	errAuthenticationRequired = "514 Authentication required\r\n"
	errUnrecognizedCommand    = "510 Unrecognized command\r\n"
)
type ProxyListener struct {
	cfg            *common.RoflcoptorConfig
	watch          bool
	authedServices []*service.MortalService
	onionDenyAddrs []common.AddrString
	errChan        chan error
	policyList     filter.PolicyList
}
func NewProxyListener(cfg *common.RoflcoptorConfig, watch bool) *ProxyListener {
	p := ProxyListener{
		cfg:        cfg,
		watch:      watch,
		policyList: filter.NewPolicyList(),
	}
	return &p
}
func (p *ProxyListener) StartListeners() {
	var err error
	log.Info("StartListeners")
	err = p.policyList.LoadFilters(p.cfg.FiltersPath)
	if err != nil {
		log.Criticalf("failed to load filter policy: %s", err)
		panic(fmt.Sprintf("failed to load filter policy: %s", err))
	}
	p.compileOnionAddrBlacklist()
	p.initAuthenticatedListeners()
}
func (p *ProxyListener) StopListeners() {
	for _, service := range p.authedServices {
		service.Stop()
	}
}
func (p *ProxyListener) compileOnionAddrBlacklist() {
	p.onionDenyAddrs = p.policyList.GetListenerAddresses()
	p.onionDenyAddrs = append(p.onionDenyAddrs, common.AddrString{
		Net:     p.cfg.TorControlNet,
		Address: p.cfg.TorControlAddress,
	})
}