diff --git a/network/router/default_router.go b/network/router/default_router.go index 5c7b73ae..322402ef 100644 --- a/network/router/default_router.go +++ b/network/router/default_router.go @@ -232,7 +232,11 @@ func (r *router) watchError(errChan <-chan error) { // stop the router if some error happened if err != nil && code != Stopped { + // this will stop watchers which will close r.advertChan close(r.exit) + // drain the advertise channel + for range r.advertChan { + } } } @@ -343,13 +347,12 @@ func (r *router) Stop() error { if r.status.Code == Running { // notify all goroutines to finish close(r.exit) + // drain the advertise channel + for range r.advertChan { + } } r.RUnlock() - // drain the advertise channel - for range r.advertChan { - } - // wait for all goroutines to finish r.wg.Wait() diff --git a/network/router/default_table.go b/network/router/default_table.go index d68398ad..ad4510dd 100644 --- a/network/router/default_table.go +++ b/network/router/default_table.go @@ -163,44 +163,44 @@ func (t *table) List() ([]Route, error) { return routes, nil } -// Lookup queries routing table and returns all routes that match it +// isMatch checks if the route matches given network and router +func isMatch(route Route, network, router string) bool { + if network == "*" || network == route.Network { + if router == "*" || router == route.Router { + return true + } + } + return false +} + +// findRoutes finds all the routes for given network and router and returns them +func findRoutes(routes map[uint64]Route, network, router string) []Route { + var results []Route + for _, route := range routes { + if isMatch(route, network, router) { + results = append(results, route) + } + } + return results +} + +// Lookup queries routing table and returns all routes that match the lookup query func (t *table) Lookup(q Query) ([]Route, error) { t.RLock() defer t.RUnlock() - var results []Route - - for destAddr, routes := range t.m { - if q.Options().Destination != "*" { - if q.Options().Destination != destAddr { - continue - } - for _, route := range routes { - if q.Options().Network == "*" || q.Options().Network == route.Network { - if q.Options().Router == "*" { - if route.Metric <= q.Options().Metric { - results = append(results, route) - } - } - } - } - } - - if q.Options().Destination == "*" { - for _, route := range routes { - if q.Options().Network == "*" || q.Options().Network == route.Network { - if q.Options().Router == "*" { - if route.Metric <= q.Options().Metric { - results = append(results, route) - } - } - } - } + if q.Options().Destination != "*" { + // no routes found for the destination and query policy is not a DiscardIfNone + if _, ok := t.m[q.Options().Destination]; !ok && q.Options().Policy != DiscardIfNone { + return nil, ErrRouteNotFound } + return findRoutes(t.m[q.Options().Destination], q.Options().Network, q.Options().Router), nil } - if len(results) == 0 && q.Options().Policy != DiscardIfNone { - return nil, ErrRouteNotFound + var results []Route + // search through all destinations + for _, routes := range t.m { + results = append(results, findRoutes(routes, q.Options().Network, q.Options().Router)...) } return results, nil diff --git a/network/router/query.go b/network/router/query.go index c479f9db..befdd1d9 100644 --- a/network/router/query.go +++ b/network/router/query.go @@ -36,44 +36,35 @@ type QueryOption func(*QueryOptions) type QueryOptions struct { // Destination is destination address Destination string - // Router is router address - Router string // Network is network address Network string - // Metric is route metric - Metric int + // Router is router address + Router string // Policy is query lookup policy Policy LookupPolicy } -// QueryDestination sets query destination address -func QueryDestination(a string) QueryOption { +// QueryDestination sets destination address +func QueryDestination(d string) QueryOption { return func(o *QueryOptions) { - o.Destination = a + o.Destination = d } } -// QueryNetwork sets query network address +// QueryNetwork sets route network address func QueryNetwork(a string) QueryOption { return func(o *QueryOptions) { o.Network = a } } -// QueryRouter sets query gateway address +// QueryRouter sets route router address func QueryRouter(r string) QueryOption { return func(o *QueryOptions) { o.Router = r } } -// QueryMetric sets query metric -func QueryMetric(m int) QueryOption { - return func(o *QueryOptions) { - o.Metric = m - } -} - // QueryPolicy sets query policy // NOTE: this might be renamed to filter or some such func QueryPolicy(p LookupPolicy) QueryOption { @@ -99,9 +90,7 @@ func NewQuery(opts ...QueryOption) Query { // NOTE: by default we use DefaultNetworkMetric qopts := QueryOptions{ Destination: "*", - Router: "*", Network: "*", - Metric: DefaultNetworkMetric, Policy: DiscardIfNone, } @@ -126,13 +115,12 @@ func (q query) String() string { // create nice table printing structure table := tablewriter.NewWriter(sb) - table.SetHeader([]string{"Destination", "Router", "Network", "Metric", "Policy"}) + table.SetHeader([]string{"Destination", "Network", "Router", "Policy"}) strQuery := []string{ q.opts.Destination, - q.opts.Router, q.opts.Network, - fmt.Sprintf("%d", q.opts.Metric), + q.opts.Router, fmt.Sprintf("%s", q.opts.Policy), } table.Append(strQuery)