Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Commit

Permalink
Improve cost calculation with new data
Browse files Browse the repository at this point in the history
  • Loading branch information
dhaavi committed Dec 21, 2021
1 parent ac4129c commit ef620a6
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 24 deletions.
2 changes: 1 addition & 1 deletion crew/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func expand(fromTerminal terminal.OpTerminal, from, to *navigator.Pin) (expansio
// connection.
type TunnelContext struct {
Path []*TunnelContextHop
PathCost int
PathCost float32
RoutingAlg string
}

Expand Down
4 changes: 2 additions & 2 deletions navigator/findnearest.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ func (nb *nearbyPins) clean() {
}

// nearbyPin represents a Pin and the proximity to a certain location.
func (nb *nearbyPin) DstCost() int {
return 100 - nb.proximity // TODO: weigh with other costs
func (nb *nearbyPin) DstCost() float32 {
return 100 - float32(nb.proximity) // TODO: weigh with other costs
}

// FindNearestHubs searches for the nearest Hubs to the given IP address. The returned Hubs must not be modified in any way.
Expand Down
2 changes: 1 addition & 1 deletion navigator/findroutes.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (m *Map) findRoutes(dsts *nearbyPins, opts *Options, maxRoutes int) (*Route
}

// Add Pin to the current path and remove when done.
route.addHop(lane.Pin, int(lane.Latency/100000))
route.addHop(lane.Pin, lane.Cost+lane.Pin.Cost)
defer route.removeHop()

// Check if the route would even make it into the list.
Expand Down
12 changes: 10 additions & 2 deletions navigator/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ type Pin struct {
LocationV6 *geoip.Location

// Hub Status
State PinState
State PinState
// HopDistance signifies the needed hops to reach this Hub.
// HopDistance is measured from the view of a client.
// A Hub itself will have itself at distance 1.
HopDistance int
Load int // estimated in microseconds this port adds to latency
// Cost is the routing cost of this Hub.
Cost float32
// ConnectedTo holds validated lanes.
ConnectedTo map[string]*Lane // Key is Hub ID.

// FailingUntil specifies until when this Hub should be regarded as failing.
Expand Down Expand Up @@ -67,6 +72,9 @@ type Lane struct {
// It is specified in nanoseconds.
Latency time.Duration

// Cost is the routing cost of this lane.
Cost float32

// active is a helper flag in order help remove abandoned Lanes.
active bool
}
Expand Down
16 changes: 8 additions & 8 deletions navigator/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

type Routes struct {
All []*Route
maxCost int // automatic
maxRoutes int // manual setting
maxCost float32 // automatic
maxRoutes int // manual setting
}

// Len is the number of elements in the collection.
Expand Down Expand Up @@ -61,14 +61,14 @@ func (r *Routes) clean() {

type Route struct {
// DstCost is the calculated cost between the Destination Hub and the destination IP.
DstCost int
DstCost float32

// Path is a list of Transit Hubs and the Destination Hub, including the Cost
// for each Hop.
Path []*Hop

// TotalCost is the sum of all costs of this Route.
TotalCost int
TotalCost float32

// Algorithm is the ID of the algorithm used to calculate the route.
Algorithm string
Expand All @@ -81,11 +81,11 @@ type Hop struct {
HubID string

// Cost is the cost for both Lane to this Hub and the Hub itself.
Cost int
Cost float32
}

// addHop adds a hop to the route.
func (r *Route) addHop(pin *Pin, cost int) {
func (r *Route) addHop(pin *Pin, cost float32) {
r.Path = append(r.Path, &Hop{
pin: pin,
Cost: cost,
Expand All @@ -95,7 +95,7 @@ func (r *Route) addHop(pin *Pin, cost int) {

// completeRoute completes the route by adding the destination cost of the
// connection between the last hop and the destination IP.
func (r *Route) completeRoute(dstCost int) {
func (r *Route) completeRoute(dstCost float32) {
r.DstCost = dstCost
r.recalculateTotalCost()
}
Expand All @@ -117,7 +117,7 @@ func (r *Route) recalculateTotalCost() {
for _, hop := range r.Path {
if hop.pin.HasActiveTerminal() {
// If we have an active connection, only take 90% of the cost.
r.TotalCost += (hop.Cost * 9) / 10
r.TotalCost += hop.Cost * 0.9
} else {
r.TotalCost += hop.Cost
}
Expand Down
2 changes: 1 addition & 1 deletion navigator/routing-profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type RoutingProfile struct {
// cost of the currently best route. This is an optimization option and
// should not interfere with finding the best route, but might reduce the
// amount of routes found.
MaxExtraCost int
MaxExtraCost float32
}

const (
Expand Down
70 changes: 61 additions & 9 deletions navigator/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,17 @@ func (m *Map) updateHub(h *hub.Hub, lockMap, lockHub bool) {
// Update Trust and Advisory Statuses.
m.updateIntelStatuses(pin)

// Update Hub load.
pin.Load = pin.Hub.Status.Load
// Update Hub cost.
switch {
case pin.Hub.Status.Load >= 100:
pin.Cost = 10000
case pin.Hub.Status.Load >= 95:
pin.Cost = 1000
case pin.Hub.Status.Load >= 80:
pin.Cost = 200
default:
pin.Cost = 50
}

// Mark all existing Lanes as inactive.
for _, lane := range pin.ConnectedTo {
Expand Down Expand Up @@ -220,6 +229,17 @@ func (m *Map) updateHub(h *hub.Hub, lockMap, lockHub bool) {
m.PushPinChanges()
}

const (
minUnconfirmedLatency = 10 * time.Millisecond
maxUnconfirmedCapacity = 100000000 // 100Mbit/s

cap1Mbit = 1000000
cap10Mbit = 10000000
cap100Mbit = 100000000
cap1Gbit = 1000000000
cap10Gbit = 10000000000
)

// updateHubLane updates a lane between two Hubs on the Map.
// pin must already be locked, lane belongs to pin.
// peer will be locked by this function.
Expand All @@ -246,29 +266,61 @@ func (m *Map) updateHubLane(pin *Pin, lane *hub.Lane, peer *Pin) {
return
}

// Calculate matching Capacity and Latency values between both Hubs.
combinedCapacity := lane.Capacity
if peerLane.Capacity < combinedCapacity {
// For Capacity, use the lesser value of both.
combinedCapacity = peerLane.Capacity
}
// Calculate combined latency, use the greater value.
combinedLatency := lane.Latency
if peerLane.Latency > combinedLatency {
// For Latency, use the greater value of both.
combinedLatency = peerLane.Latency
}
// Enforce minimum value if at least one side has no data.
if (lane.Latency == 0 || peerLane.Latency == 0) && combinedLatency < minUnconfirmedLatency {
combinedLatency = minUnconfirmedLatency
}

// Calculate combined capacity, use the lesser existing value.
combinedCapacity := lane.Capacity
if combinedCapacity == 0 || (peerLane.Capacity > 0 && peerLane.Capacity < combinedCapacity) {
combinedCapacity = peerLane.Capacity
}
// Enforce maximum value if at least one side has no data.
if (lane.Capacity == 0 || peerLane.Capacity == 0) && combinedCapacity > maxUnconfirmedCapacity {
combinedCapacity = maxUnconfirmedCapacity
}

// Calculate cost:
var laneCost float32
// - One point for every ms in latency (linear)
laneCost += float32(combinedLatency) / float32(time.Millisecond)
switch {
case combinedCapacity < cap1Mbit:
// - Between 1000 and 10000 points for ranges below 1Mbit/s
laneCost += 1000 + 9000*((cap1Mbit-float32(combinedCapacity))/cap1Mbit)
case combinedCapacity < cap10Mbit:
// - Between 200 and 1000 points for ranges below 10Mbit/s
laneCost += 200 + 800*((cap10Mbit-float32(combinedCapacity))/cap10Mbit)
case combinedCapacity < cap100Mbit:
// - Between 20 and 200 points for ranges below 100Mbit/s
laneCost += 20 + 180*((cap100Mbit-float32(combinedCapacity))/cap100Mbit)
case combinedCapacity < cap1Gbit:
// - Between 5 and 20 points for ranges below 1Gbit/s
laneCost += 5 + 15*((cap1Gbit-float32(combinedCapacity))/cap1Gbit)
case combinedCapacity < cap10Gbit:
// - Between 0 and 5 points for ranges below 10Gbit/s
laneCost += 5 * ((cap10Gbit - float32(combinedCapacity)) / cap10Gbit)
}

// Add Lane to both Pins and override old values in the process.
pin.ConnectedTo[peer.Hub.ID] = &Lane{
Pin: peer,
Capacity: combinedCapacity,
Latency: combinedLatency,
Cost: laneCost,
active: true,
}
peer.ConnectedTo[pin.Hub.ID] = &Lane{
Pin: pin,
Capacity: combinedCapacity,
Latency: combinedLatency,
Cost: laneCost,
active: true,
}
peer.pushChanges.Set()
Expand Down

0 comments on commit ef620a6

Please sign in to comment.