135 lines
2.9 KiB
Go
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
|