added in memory prefix lookup

This commit is contained in:
Matthias Hannig 2017-06-23 16:11:47 +02:00
parent 071df811ca
commit 8fe92d21f3
5 changed files with 97 additions and 48 deletions

View File

@ -7,6 +7,7 @@ import (
"net/http"
"strconv"
"strings"
"time"
"github.com/ecix/alice-lg/backend/api"
@ -215,34 +216,19 @@ func apiRoutesList(_req *http.Request, params httprouter.Params) (api.Response,
// Handle global lookup
func apiLookupPrefixGlobal(req *http.Request, params httprouter.Params) (api.Response, error) {
// Get prefix to query
/*
prefix, err := validateQueryString(req, "q")
if err != nil {
return nil, err
}
// Run query on all sources
rsCount := len(AliceConfig.Sources)
responses := make(chan api.LookupResponse, rsCount)
for _, src := range AliceConfig.Sources {
go func(src SourceConfig) {
// Run query on RS
rs := src.getInstance()
result, _ := rs.LookupPrefix(prefix)
responses <- result
}(src)
}
// Collect results
routes := []api.LookupRoute{}
for i := 0; i < rsCount; i++ {
result := <-responses
routes = append(routes, result.Routes...)
}
*/
prefix, err := validateQueryString(req, "q")
if err != nil {
return nil, err
}
// Make response
response := api.LookupResponseGlobal{}
t0 := time.Now()
routes := AliceRoutesStore.Lookup(prefix)
queryDuration := time.Since(t0)
response := api.LookupResponseGlobal{
Routes: routes,
Time: float64(queryDuration) / 1000.0 / 1000.0, // nano -> micro -> milli
}
return response, nil
}

View File

@ -9,6 +9,7 @@ import (
)
var AliceConfig *Config
var AliceRoutesStore *RoutesStore
func main() {
var err error
@ -33,8 +34,8 @@ func main() {
log.Println("Using configuration:", AliceConfig.File)
// Setup local routes store
routesStore := NewRoutesStore(AliceConfig)
routesStore.Start()
AliceRoutesStore = NewRoutesStore(AliceConfig)
AliceRoutesStore.Start()
// Setup request routing
router := httprouter.New()

View File

@ -5,6 +5,7 @@ import (
"github.com/ecix/alice-lg/backend/sources"
"log"
"strings"
"time"
)
@ -192,8 +193,89 @@ func (self *RoutesStore) Stats() StoreStats {
return storeStats
}
// Routes filter
func filterRoutes(
config SourceConfig,
routes []api.Route,
prefix string,
state string,
) []api.LookupRoute {
results := []api.LookupRoute{}
for _, route := range routes {
// Naiive filtering:
if strings.HasPrefix(route.Network, prefix) {
lookup := api.LookupRoute{
Id: route.Id,
NeighbourId: route.NeighbourId,
Routeserver: api.Routeserver{
Id: config.Id,
Name: config.Name,
},
State: state,
Network: route.Network,
Interface: route.Interface,
Gateway: route.Gateway,
Metric: route.Metric,
Bgp: route.Bgp,
Age: route.Age,
Type: route.Type,
}
results = append(results, lookup)
}
}
return results
}
// Single RS lookup
func (self *RoutesStore) lookupRs(
source sources.Source,
prefix string,
) chan []api.LookupRoute {
response := make(chan []api.LookupRoute)
config := self.configMap[source]
routes := self.routesMap[source]
go func() {
filtered := filterRoutes(
config,
routes.Filtered,
prefix,
"filtered")
imported := filterRoutes(
config,
routes.Imported,
prefix,
"imported")
result := append(filtered, imported...)
response <- result
}()
return response
}
func (self *RoutesStore) Lookup(prefix string) []api.LookupRoute {
result := []api.LookupRoute{}
responses := []chan []api.LookupRoute{}
// Dispatch
for source, _ := range self.routesMap {
res := self.lookupRs(source, prefix)
responses = append(responses, res)
}
// Collect
for _, response := range responses {
routes := <-response
result = append(result, routes...)
}
return result
}

View File

@ -1,9 +0,0 @@
package main
import (
"testing"
)
func TestLookup(t *testing.T) {
t.Log("Building test store")
}

View File

@ -116,13 +116,6 @@ func (self *Birdwatcher) LookupPrefix(prefix string) (api.LookupResponse, error)
Name: self.config.Name,
}
// Get neighbours list from RS
neighboursRes, err := self.Neighbours()
if err != nil {
return api.LookupResponse{}, err
}
neighbours := neighboursRes.Neighbours
// Query prefix on RS
bird, err := self.client.GetJson("/routes/prefix?prefix=" + prefix)
if err != nil {
@ -141,9 +134,6 @@ func (self *Birdwatcher) LookupPrefix(prefix string) (api.LookupResponse, error)
// Add corresponding neighbour and source rs to result
results := []api.LookupRoute{}
for _, src := range routes {
// Get corresponding neighbour
neighbour, _ := getNeighbourById(neighbours, src.NeighbourId)
// Okay. This is actually really hacky.
// A less bruteforce approach would be highly appreciated
route := api.LookupRoute{
@ -152,7 +142,6 @@ func (self *Birdwatcher) LookupPrefix(prefix string) (api.LookupResponse, error)
Routeserver: rs,
NeighbourId: src.NeighbourId,
Neighbour: neighbour,
Network: src.Network,
Interface: src.Interface,