lgregmapper/fakememcache.go
2019-02-21 14:13:35 +00:00

135 lines
2.9 KiB
Go

//////////////////////////////////////////////////////////////////////////
// lgregmapper, a small utility to provide DN42 registry data to bird-lg
//////////////////////////////////////////////////////////////////////////
package main
//////////////////////////////////////////////////////////////////////////
import (
// "fmt"
"bufio"
log "github.com/sirupsen/logrus"
"net"
"strings"
"sync"
)
//////////////////////////////////////////////////////////////////////////
type FakeMemcache struct {
done chan bool
wait *sync.WaitGroup
regClient *RegClient
}
//////////////////////////////////////////////////////////////////////////
// create a new fakememcache object
func NewFakeMemcache(regClient *RegClient) *FakeMemcache {
fmc := &FakeMemcache{
done: make(chan bool),
wait: &sync.WaitGroup{},
regClient: regClient,
}
fmc.wait.Add(1)
return fmc
}
//////////////////////////////////////////////////////////////////////////
// do the serving thing
func (fmc *FakeMemcache) Start(listener net.Listener) {
defer listener.Close()
defer fmc.wait.Done()
// listen and respond to connection or errors
go func() {
for {
conn, err := listener.Accept()
if err != nil {
// check if due to shutdown
select {
case <-fmc.done:
return
default:
}
// not shutdown, log an error and try again
log.WithFields(log.Fields{
"Error": err,
"addr": listener.Addr(),
}).Error("Listener accept error")
} else {
fmc.wait.Add(1)
go fmc.Serve(conn)
}
}
}()
// block waiting for done
<-fmc.done
}
//////////////////////////////////////////////////////////////////////////
// serve a single client
func (fmc *FakeMemcache) Serve(conn net.Conn) {
defer conn.Close()
defer fmc.wait.Done()
log.WithFields(log.Fields{
"Remote": conn.RemoteAddr(),
}).Debug("Accepted Connection")
// read lines from the client
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
command := strings.TrimSpace(scanner.Text())
// only respond to 'get' requests
if strings.HasPrefix(command, "get ") {
key := strings.TrimPrefix(command, "get ")
if data := fmc.regClient.ASN[key]; data == nil {
log.WithFields(log.Fields{
"command": command,
"remote": conn.RemoteAddr(),
}).Debug("Unknown key")
} else {
// return the cached data
conn.Write(data)
}
} else {
log.WithFields(log.Fields{
"command": command,
"remote": conn.RemoteAddr(),
}).Debug("Received unknown command")
}
}
log.WithFields(log.Fields{
"Remote": conn.RemoteAddr(),
}).Debug("Closing Connection")
}
//////////////////////////////////////////////////////////////////////////
// shutdown the server
func (fmc *FakeMemcache) Shutdown() {
// signal shutdown and wait to complete
close(fmc.done)
// fmc.wait.Wait()
log.Info("FakeMemcache shutdown")
}
//////////////////////////////////////////////////////////////////////////
// end of code